embracing async with deferreds and promises
TRANSCRIPT
Embracing Async with Deferreds & promises
Sebastian Porto@sebasporto
Let’s do greeting card
Animation 1
Animation 2
Music 1
Music 2
Next
Load animation !
Load music !
Show !
Select !animation !
& !music !
Knowing everything at the start
var assetsToLoad=2;loader.on(‘load’, function(){
assetsToLoad --;if(assetsToLoad===0) show();
});loader.load(anim);loader.load(music);
We can count
Use a lib (e.g. Async)
async.parallel([
loadAnim,loadMusic,
], show);
Check Async by the way
Async is nice and clean but…
Animation 1
Animation 2
Music 1
Music 2
Load animation !
Load music !
Show !
Select !animation !
Select !music !
Wait? !
Incomplete information
Load animation !
Load music !
Show !
Select !animation !
Incomplete information
Select !music !
function onVideoLoaded(){checkIfAllLoaded();
}function checkIfAllLoaded(){
if(videoLoaded && musicLoaded && … ) show();}
We can count again or"use conditionals
Becomes hard to maintain very quickly
Deferreds to the rescue
var def = $.Deferred();def.done(function(val){
//… do something});//… laterdef.resolve(val);
jQuery Deferreds"Underscore deferreds"
PromisedIO"… many others"
They can be aggregated
var def1 = $.Deferred();var def2 = $.Deferred();$.when(def1, def2).done(function(one, two){
//… do something with one and two;});//… laterdef1.resolve(val);//… even laterdef2.resolve(val);
Load animation !
Load music !
Show !
Select !animation !
Select !music !
To do this
var animDef = $.Deferred();var musicDef = $.Deferred();$.when(animDef, musicDef).done(function(){
show(); });//when the music is loadedmusicDef.resolve();//when the animation is loadedanimDef.resolve();
Load animation !
Load music !
Show !
Select !animation !
Select !music !
Already resolved?
var animDef = $.Deferred();var musicDef = $.Deferred();//…latermusicDef.resolve();//…even later$.when(animDef, musicDef).done(function(){
show(); });//No problem, still triggers, you cannot do that with event listeners!
Fail and reject
var def = $.Deferred();def
.done(function(result){ //do something}).fail(function(){ //fallback});
//…later, something bad happeneddef.reject();
Promises
Promises
Loaderfunction load(){
def = $.Deferred();return def.promise();
}//..laterfunction onLoad(){
def.resolve();}
Callerpromise = loader.load();promise.done(function(){
..something});//Cannot resolve here://promise.resolve() not possible
Combine them to create bigger promises
var promise1 = $.when(animDef, musDef);var promise2 = $.when(msgDef, bgDef);$.when(promise1, promise2).done(function(){
//… do something with anim, music message and background});
A !
C !
Result !
B !
F !
D !
E !
G !
H !