Javascript assíncrono - Um bate-papo sobre event loop, event queue, callbacks e promises

Post on 28-Nov-2014

370 views 4 download

description

 

Transcript of Javascript assíncrono - Um bate-papo sobre event loop, event queue, callbacks e promises

Javascript assíncrono

@cezinha_anjos 1

Um bate-papo sobre event loop, event queue, callbacks e promises

@cezinha_anjos• Programo há 25 anos, sendo

que já passei por diversas linguagens e paradigmas de programação.

• Estou atualmente focado em tecnologias web, principalmente em Ruby on Rails e Javascript.

• Amante de OO, Clean Code, Design Patterns, BDD e Lean.

• Sou diretor da ASSEINFO.

2

3

console.clear(); console.log("a"); !

setTimeout(function(){ console.log("b"); }, 2000);

console.log("c"); !

setTimeout(function(){ console.log("d"); }, 1000);

4

console.clear(); console.log("a"); !

setTimeout(function(){ console.log("b"); }, 2000);

console.log("c"); !

setTimeout(function(){ console.log("d"); }, 1000);

abcd

Saída esperada

após 1 seg.

após 2 seg.

imediato

imediato

5

console.clear(); console.log("a"); !

setTimeout(function(){ console.log("b"); }, 2000);

console.log("c"); !

setTimeout(function(){ console.log("d"); }, 1000);

acdb

Saída de fato

após 1 seg.

após 2 seg.

imediato

imediato

Por que a execução não para e aguarda o

setTimeout?

6

Por que o setTimeout de 1 seg. retornou antes do

de 2seg.?

7

resposta: event loop

8

9

event queue

event loop

single thread

JS VM / libuvS.O. workers outros

10

console.clear(); console.log("a"); !

setTimeout(function(){ console.log("b"); }, 2000);

console.log("c"); !

setTimeout(function(){ console.log("d"); }, 1000);

executa

executa

agenda

agenda

11

setTimeout - 2000

setTimeout - 1000

event queue

event loop

single thread

JS VM / libuvS.O. workers outros

outro exemplo

12

Bloqueantevar start = new Date(); !

for(var i = 0; i < 100000000; i++) { }; for(var i = 0; i < 100000000; i++) { }; !

console.log(new Date() - start, “ms"); # 545 ms

13

Não bloqueantevar start = new Date(); !setTimeout(function() { for(var i = 0; i < 100000000; i++) { }; }, 0); !setTimeout(function() { for(var i = 0; i < 100000000; i++) { }; }, 0); !console.log(new Date() - start, “ms"); # 11 ms

14

De 545 ms para 11 ms? Será que rodou tudo?

15

var start = new Date(), count = 0; setTimeout(function() { for(var i = 0; i < 100000000; i++) { }; count++; }, 0); !setTimeout(function() { for(var i = 0; i < 100000000; i++) { }; count++ }, 0); !console.log(new Date() - start, “ms”); console.log(count, “ocorrências”); # 11 ms # 0 ocorrências ———————————————— console.log(count, “ocorrências”); # 2 ocorrências

16

!

Não programe async confiando que a resposta virá

em uma determinada sequência ou imediatamente.

!

#FicaDica

17

callbacks

18

Um callback é a maneira mais básica de ser notificado sobre um retorno assíncrono.

19

São simplesmente funções passadas como parâmetro para chamadas assíncronas.

20

21

!

setTimeout(myCallback, 2000);

function myCallback() { console.log( “Passou-se pelo menos 2 segundos” ); }

Uma implementação mais popular

22

23

$(“button#add”).on(“click”, function(){ console.log(“Botão add foi clicado"); });

$(“button#add”).on(“click”, myCallback);

function myCallback() { console.log(“Botão add foi clicado”); }

OU

Dois callbacks para o mesmo evento

24

25

$(“button#add”).on(“click”, myCallback1); $(“button#add”).on(“click”, myCallback2);

function myCallback1() { console.log(“Callback 1 foi disparado”); } !

function myCallback2() { console.log(“Callback 2 foi disparado”); }

Somente elementos que implementem o padrão Observer permitem mais de um callback.

!

O event loop só responde a um callback.

26

27

Callback1 Callback2

notificador

click

JQuery.on() e AddEventListener() são implementações de Observers

28

$.Deferred();

29

30

var deferred = $.Deferred(); !

deferred.done(function(){ console.log(“Deferido"); }); !

deferred.fail(function(){ console.log(“Indeferido"); }); !

deferred.always(function(){ console.log(“Sempre"); });

deferred.resolve(); Deferido Sempre !

!

deferred.reject(); Indeferido Sempre

Saída do console

deferred.promise()

31

Promise é um subset de deferred. A diferença entre eles é que promise não possui os métodos resolve() e reject()

32

Onde promise é usado?

33

34

var response = $.ajax({ url: “/person.json”, data: {id: 1}, dataType: “json” }); !response.always(function(){ console.clear(); }); !response.done(function(person){ console.log(person); }); !response.fail(function(){ console.log(“Person not found"); });

Por que não deferred?

35

36

var response = $.ajax({ url: “/person.json”, data: {id: 1}, dataType: “json” }); !response.reject(); !response.always(function(){ console.clear(); }); !response.done(function(person){ console.log(person); }); !response.fail(function(){ console.log(“Person not found"); });

por isso!

Legal… mas posso usar nas minhas

implementações?

37

38

function sayMyName(name) { var deferred = $.Deferred(); ! if (name === “Heisenberg”) { deferred.resolve(); } else { deferred.reject(); } ! return deferred.promise(); } !sayMyName(“Jesse Pinkman”) .always(function(){ console.clear(); }) .done(function(){ console.log(“You know my name!”); }) .fail(function(){ console.log(“It’s better call Saul!”); }) ;

Muito obrigado!

@cezinha_anjos

cezinha.info

asseinfo.com.br

39