Slide 1

Slide 1 text

Marcel Gonçalves dos Santos @marcelgsantos programação assíncrona em JavaScript do básico ao avançado

Slide 2

Slide 2 text

pensandonaweb.com.br desenvolvedor web full-stack Marcel Gonçalves dos Santos @marcelgsantos

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

@femugsp sp.femug.com

Slide 5

Slide 5 text

@phpsp phpsp.org.br

Slide 6

Slide 6 text

Interaja nas mídias sociais!
 
 - fale sobre o evento, palestrantes e conteúdo - tire fotos do evento e publique
 - interaja com outros participantes do evento - tire dúvidas ou dê feedbacks para os palestrantes

Slide 7

Slide 7 text

1. seguir @marcelgsantos no Twitter
 2. tuitar utilizando as hashtags #TheDevConf, #TrilhaJavaScript e #Async
 3. não vale tuíte em branco e retuíte
 4. ler e preencher este simples formulário
 bit.ly/sorteio-tdc-sp-2 Concorra a um livro da Casa do Código!

Slide 8

Slide 8 text

Fluxo de execução de um programa

Slide 9

Slide 9 text

o fluxo de execução de um programa é determinado pela ordem em que suas instruções são executadas

Slide 10

Slide 10 text

normalmente é sequencial e segue a ordem em que as instruções aparecem no código

Slide 11

Slide 11 text

existem diversas instruções para guiar o fluxo de execução como if, else, for, while, try…catch entre outras

Slide 12

Slide 12 text

!// execution flow 
 let val1 = prompt('Input the first value:'); let val2 = prompt('Input the second value:'); val1 = parseInt(val1); val2 = parseInt(val2); if ((val1 !>= 1 !&& val1 !<=10) !&& (val2!>= 1 !&& val2 !<=10)) { let result = sum(val1, val2); console.log('The result is %d.', result); } else { console.log('There was a problem during the calculation.'); }

Slide 13

Slide 13 text

o JavaScript possui um fluxo único de execução que ocorre na thread principal

Slide 14

Slide 14 text

a thread principal é compartilhada entre a renderização da página e códigos JavaScript

Slide 15

Slide 15 text

em JavaScript um fluxo de execução pode ser síncrono ou assíncrono

Slide 16

Slide 16 text

Fluxos síncronos e assíncronos

Slide 17

Slide 17 text

um código é síncrono quando uma instrução é executada somente quando a instrução anterior estiver terminado

Slide 18

Slide 18 text

!// synchronous code
 let val1 = prompt('Input the first value:'); let val2 = prompt('Input the second value:'); val1 = parseInt(val1); val2 = parseInt(val2); if ((val1 !>= 1 !&& val1 !<=10) !&& (val2!>= 1 !&& val2 !<=10)) { let result = sum(val1, val2); console.log('The result is %d.', result); } else { console.log('There was a problem during the calculation.'); }

Slide 19

Slide 19 text

um código síncrono é simples de entender e fácil de ler

Slide 20

Slide 20 text

um código é assíncrono quando as instruções podem ser executadas sem ordem definida

Slide 21

Slide 21 text

um código assíncrono é complicado de entender e difícil de ler

Slide 22

Slide 22 text

!// asynchronous code fs.readFile('lorem.txt', {encoding: 'utf8'}, function(err, text) { if (err) { console.log('Houston, we have a problem!'); return; }
 console.log(text); !// [2] Lorem ipsum dolor sit amet!!... }); console.log('Finished'); !// [1] Finished

Slide 23

Slide 23 text

porém, um código assíncrono permite que o seu programa tenha um melhor desempenho

Slide 24

Slide 24 text

Código bloqueante e não-bloqueante

Slide 25

Slide 25 text

um código bloqueante é aquele que bloqueia a execução de uma instrução até que a instrução anterior seja finalizada

Slide 26

Slide 26 text

o conceito foi inventado para tornar a programação mais fácil

Slide 27

Slide 27 text

o espirro é algo bloqueante, ou seja, paramos “tudo” o que estamos fazendo quando vamos espirrar!

Slide 28

Slide 28 text

um código não-bloqueante é aquele que não bloqueia a execução de uma instrução com base em uma instrução anterior não finalizada

Slide 29

Slide 29 text

o ser humano é multitarefa e pode andar, falar e comer ao mesmo tempo, ou seja, são tarefas não-bloqueantes

Slide 30

Slide 30 text

o hardware de um computador funciona de forma não-bloqueante e assíncrona

Slide 31

Slide 31 text

é a linguagem que adiciona a semântica bloqueante e síncrona

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

perde-se muitos ciclos de CPU quando se espera disco e rede

Slide 34

Slide 34 text

esse é o motivo pelo qual o hardware é assíncrono

Slide 35

Slide 35 text

queremos a CPU rodando na capacidade máxima

Slide 36

Slide 36 text

ou seja, assíncrono e não-bloqueante possui melhor desempenho

Slide 37

Slide 37 text

Programação orientada à eventos
 event-driven programming

Slide 38

Slide 38 text

pode-se utilizar eventos para implementar assincronicidade

Slide 39

Slide 39 text

o Node.js abstrai as operações de I/O utilizando eventos

Slide 40

Slide 40 text

o JavaScript é executado em um única thread, ela é conhecida como main thread ou thread principal

Slide 41

Slide 41 text

porém threads auxiliares são utilizadas para outras operações

Slide 42

Slide 42 text

utiliza-se eventos para sincronizar as tarefas entre a main-thread e as threads auxiliares

Slide 43

Slide 43 text

Como utilizar a programação assíncrona
 em JavaScript

Slide 44

Slide 44 text

existem vários padrões de programação assíncrona em JavaScript

Slide 45

Slide 45 text

eventos
 
 pode-se receber resultados de computação assíncrona utilizando eventos

Slide 46

Slide 46 text

eventos
 
 para isso deve-se registrar manipuladores de eventos ou event handler para um objeto

Slide 47

Slide 47 text

var request = new XMLHttpRequest(); request.open('GET', 'https:!//swapi.co/api/people/1/'); request.onload = function() { !// add event handler if (request.status !== 200) { console.log(JSON.parse(request.response)); } else { console.log('error:', request.statusText); } }; request.onerror = function() { !// add event handler console.log('request error'); } request.send(); !// add request to task queue console.log('finish script');

Slide 48

Slide 48 text

var request = new XMLHttpRequest(); request.open('GET', 'https:!//swapi.co/api/people/1/'); request.onload = function() { !// add event handler if (request.status !== 200) { console.log(JSON.parse(request.response)); } else { console.log('error:', request.statusText); } }; request.onerror = function() { !// add event handler console.log('request error'); } request.send(); !// add request to task queue console.log('finish script');

Slide 49

Slide 49 text

var request = new XMLHttpRequest(); request.open('GET', 'https:!//swapi.co/api/people/1/'); request.onload = function() { !// add event handler if (request.status !== 200) { console.log(JSON.parse(request.response)); } else { console.log('error:', request.statusText); } }; request.onerror = function() { !// add event handler console.log('request error'); } request.send(); !// add request to task queue console.log('finish script');

Slide 50

Slide 50 text

var request = new XMLHttpRequest(); request.open('GET', 'https:!//swapi.co/api/people/1/'); request.onload = function() { !// add event handler if (request.status !== 200) { console.log(JSON.parse(request.response)); } else { console.log('error:', request.statusText); } }; request.onerror = function() { !// add event handler console.log('request error'); } request.send(); !// add request to task queue console.log('finish script');

Slide 51

Slide 51 text

ao utilizar um objeto XMLHttpRequest deve- se chamar explicitamente o método send() para adicionar a requisição na fila de tarefas

Slide 52

Slide 52 text

contudo, existem APIs que não é necessário fazer isso de forma explícita

Slide 53

Slide 53 text

callbacks
 
 os callbacks são porções de código (normalmente funções) que são executados em um tempo no futuro

Slide 54

Slide 54 text

callbacks
 
 sempre quando uma tarefa assíncrona entra em ação, o callback é registrado e espera por uma mensagem para ser executado

Slide 55

Slide 55 text

callbacks
 
 existe um loop de eventos que aguarda por mensagens

Slide 56

Slide 56 text

callbacks
 
 as funções de callback que possuem acesso às variáveis do escopo em que foram definidas são chamadas de closures

Slide 57

Slide 57 text

!// callback example
 
 console.log('Before setTimeout'); !// [1] setTimeout(() !=> { console.log('Callback added to the task queue executed!’); !// [3] }, 1000); !// after 1s the callback is added to the task queue console.log('After setTimeout'); !// [2]

Slide 58

Slide 58 text

!// callback example (2)
 
 console.log('Before setTimeout'); !// [1] setTimeout(() !=> { console.log('Callback added to the task queue executed!’); !// [?] }, 0); console.log('After setTimeout'); !// [?]

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

callbacks
 
 uma das limitações de se utilizar callbacks é o callback hell

Slide 61

Slide 61 text

!// callback hell module.asyncFunction((response1) !=> { response1.asyncFunction((response2) !=> { response2.asyncFunction((response3) !=> { response3.asyncFunction((response4) !=> { return response4; }); }); }); });

Slide 62

Slide 62 text

promises
 
 elas são uma alternativa para callbacks para entregar resultados de uma computação assíncrona

Slide 63

Slide 63 text

promises
 
 uma promise representa o possível 
 resultado de uma operação assíncrona

Slide 64

Slide 64 text

!// promise (result of a request using fetch) const req = fetch('https:!//httpbin.org/delay/3'); console.log(req); 
 
 !// Promise {status: "pending", value: undefined}

Slide 65

Slide 65 text

promises
 
 utiliza-se a função then() para atribuir funções de callback para promises

Slide 66

Slide 66 text

promises
 
 e as funções de callback podem ser encadeadas

Slide 67

Slide 67 text

!// using then to resolve a promise fetch('https:!//httpbin.org/ip') .then(response !=> response.json()) .then(result !=> console.log(result));
 !// {origin: "187.182.22.229, 187.182.22.229"}

Slide 68

Slide 68 text

promises
 
 uma promise pode estar em três estados: pending, fulfilled ou rejected

Slide 69

Slide 69 text

promises
 
 se uma promise não está mais pending, ela está settled

Slide 70

Slide 70 text

!// create a promise (resolved) const promise = new Promise(function (resolve, reject) { if (true) { resolve('This promise was resolved.'); } else { reject('This promise was rejected!'); } }); promise.then(result !=> console.log(result)); 
 !// This promise was resolved.

Slide 71

Slide 71 text

!// creating a promise (rejected) const promise = new Promise(function (resolve, reject) { if (false) { resolve('This promise was resolved.'); } else { reject('This promise was rejected!'); } }); promise.then( result !=> console.log(result), error !=> console.error(error) ); !// This promise was rejected!

Slide 72

Slide 72 text

/ creating a promise (rejected) const promise = new Promise(function (resolve, reject) { if (false) { resolve('This promise was resolved.'); } else { reject('This promise was rejected!'); } }); promise .then(result !=> console.log(result)) .catch(error !=> console.error(error)); 
 !// This promise was rejected!

Slide 73

Slide 73 text

promises
 
 utiliza-se a função Promise.all() para receber uma notificação quando todas as promises forem resolvidas

Slide 74

Slide 74 text

!// notify when all promises were fulfilled (after 5s) Promise.all([ fetch('https:!//httpbin.org/delay/5'), fetch('https:!//httpbin.org/delay/3'), ]).then(result !=> console.log('Ok!', result)); !// Ok! (2) [Response, Response]

Slide 75

Slide 75 text

promises
 
 utiliza-se a função Promise.race() para retornar a primeira promise de uma lista que foi resolvida ou rejeitada

Slide 76

Slide 76 text

async e await
 
 é uma forma mais moderna de se receber resultados de computação assíncrona

Slide 77

Slide 77 text

!// using async and await async function getCharacter(id) { const res = await fetch(`https:!//swapi.co/api/people/${id}/`); const data = await res.json(); return data; } getCharacter(1) .then(luke !=> console.log(luke)); !// {name: "Luke Skywalker", height: "172", …}

Slide 78

Slide 78 text

async e await
 
 funciona seguindo a especificação de promises

Slide 79

Slide 79 text

async e await
 
 a palavra-chave async é utiliza no início da função para indicar que ela será assíncrona

Slide 80

Slide 80 text

async e await
 
 a palavra-chave await informa o código para esperar a promise ser resolvida antes de continuar a execução

Slide 81

Slide 81 text

async e await
 
 a palavra-chave await só pode ser utilizado em funções com async

Slide 82

Slide 82 text

async e await
 
 possui suporte na maioria dos navegadores modernos e no Node.js

Slide 83

Slide 83 text

async e await
 
 torna o código mais simples de ler e mais fácil de depurar

Slide 84

Slide 84 text

Conclusão

Slide 85

Slide 85 text

o JavaScript possui uma natureza assíncrona e é importante compreendê-la bem

Slide 86

Slide 86 text

a utilização de código assíncrono é essencial para desempenho

Slide 87

Slide 87 text

Referências

Slide 88

Slide 88 text

bit.ly/referencias-palestra-async

Slide 89

Slide 89 text

Avalie!

Slide 90

Slide 90 text

bit.ly/avalie-palestra-async

Slide 91

Slide 91 text

@marcelgsantos speakerdeck.com/marcelgsantos Obrigado. Perguntas?