Date post: | 28-Nov-2014 |
Category: |
Software |
Upload: | cezinha-anjos |
View: | 371 times |
Download: | 4 times |
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