Skip to main content
Promises & Deferreds
look into the async future
@slicejs
Plan
1. Introduction
2. What problem promises can solve ?
3. Promises in jQuery
Promises are a
programming construct
that have been around
since 1976.
http://en.wikipedia.org/wiki/Futures_and_promises
Brief History of Promises
● Term was first used by C++ engineers on the Xanadu project (1976)
● 2007: Dojo Framework added dojo.Deferred
● 2009: dojo.Deferred influenced Kris Zyp - Proposal of CommonJS
Promises/A spec.
● 2009: Node.js - used Promises in its non blocking API
● 2009: two implementations (Kris Kowal Q.js and O'Neill Futures.js)
● 2011: jQuery rewrites Ajax - ( not 100% CommonJS spec compliant )
20071976 2009 2011
What is a Promise ?
A Promise is an object that represents a task with two
possible outcomes (success or failure)
holds callbacks that fire when one outcome or the
other has occurred
Promises & Deferreds
Promise represents a value that is not yet
known
Deferred represents work that is not yet
finished
CommonJS Promises/A spec
Proposal by Kris Zyp
What's inside ?
The Promises /A Proposal suggests the following standard behavior and API
regardless of implementation details.
A promise has 3 possible states: unfulfilled, fulfilled and failed.
● unfulfilled: since a promise is a proxy for an unknown value it starts in
an unfulfilled state
● fulfilled: the promise is filled with the value it was waiting for
● failed: if the promise was returned an exception, it is in the failed state.
then(
fulfilledHandler,
errorHandler,
progressHandler
);
What's inside
A promise:
● has a function as a value for the property then
(which must return a promise )
● Adds a fulfilledHandler, errorHandler, and progressHandler to be called
for completion of a promise.
● then(fulfilledHandler, errorHandler, progressHandler);
Current implementations
● Kris Kowal’s Q.js
● AJ O'Neal’s FuturesJS
● jQuery since 1.5
Q.js - implementation of the Promises/A spec
Futures - is a broader toolkit, incorporating many of the flow control
features found in libraries like Async.js.
jQuery - not 100% Promises/A compliant.
https://github.com/kriskowal/q
https://github.com/coolaj86/futures
Why do we need
promises ?
sync !== async
But they exist parallely
How do we manage this ?
Anybody ?
We used to use callbacks
A callback is a piece of executable code that is passed as
an argument to other code, which is expected to call back
(execute ) the argument at some convenient time
— Wikipedia
There's nothing wrong
with them
until...
Do you know that ?
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
Such a case - "Taka sytuacja"
● make an Ajax request to get some data
● do something with data, then
● do other things
Insights
● request is made
● execution of our program isn't stopped while the server is responding
● By the time we get the response data from our Ajax request, the
program has already finished execution
Wouldn't be better
doStuff();
that way ?
var $doStuff = $.Deferred();
$doStuff
.done(doOtherStuff)
.fail(keepCalmAndDrinkWine);
doStuff() - easier way
Let's take a closer
look on Deferred
object
then
Deferred
Promise
(A)Handlers States
$.then() $.when()
has
has has
based on
represented by
as unfinished work
as yet unknown value
what to do once work is done
ad value is known
pending = unfulfilled = waiting
fulfilled = resolved = success
rejected = failed = error
hold off doing things until you
have result of doing that
Deferred object
execute callbacks based on one
or more objects that represents
async events
Promise - states & flows
Promise
unfulfilled fulfilled
failed
Promises can help
We can write
asynchronous JavaScript
parallel to how we write
synchronous code
Where to use promises
● Ajax
● Timing tasks (games)
● Synchronizing parallel tasks with $.when()
● Decoupling events and application logic
● Animations
We love jQuery (don't we ?)
Let's take a look at their
implementation
jQuery 1.5 changed Mr. Ajax
since(version1.5) {
$.ajax();
$.get();
$.post();
return Promises;
} that's amazing !
Deferreds team in complete
$.Deferred();
deferred.always();
deferred.then();
deferred.when();
deferred.resolve(); or deferred.reject();
deferred.promise();
deferred.state();
deferred.done();
deferred.fail();
$.ajax();
How to use them ?
Instantiate Deferred
var future = $.Deferred();
$.Deferred()
A constructor that creates a new deferred object.
Accepts an optional init function which will be executed
immediately after the deferred is created.
Place your toys & voila
var step1, step2, url;
url = 'example.json';
step1 = $.ajax(url);
step2 = step1.then(
function (data) {
setTimeout(function () {
console.log('Request completed');
}, 3000);
});
step2.done(function () {
console.log('Sequence completed')
});
});
deferred.then();
Adds handlers which will be called on
● resolved
● rejected or in
● progress
and
returns a promise;
deferred.when();
Returns a new promise based on the completion of
multiple promises.
If any promise is rejected,
.when() is rejected and if all promises are resolved, it is
resolved.
deferred.when();
function taskOne() {
setTimeout(function() {
console.log('task1');
}, 1000);
}
function taskTwo() {
setTimeout(function() {
console.log('task1');
}, 3000);
}
$.when(taskOne, taskTwo).done(function () {
console.log('taskOne and taskTwo are finished');
});
Example
var prompt = $.Deferred();
$('#playGame').focus().on('keypress', function(e) {
var Y = 121, N = 110;
if(e.keyCode === Y) {
prompt.resolve();
} else if (e.keyCode === N) {
prompt.reject();
} else {
return false;
}
});
prompt.always(function(){console.log('A choice was made:');});
prompt.done(function(){ console.log('Starting game...'); });
prompt.fail(function(){ console.log('No game today.'); });
Few things to remember
● callbacks in order in which they were bound
● Promise can be resolved or rejected only once
jQuery vs. CommonJs Promises/A
● implementation are nearly identical
● they use the same words to mean different things
● jQuery uses resolve as opposite of fail
● Promises/A uses fullfill
● jQ 1.8 then method (shorthand done, fail and progress)
● jQ then === pipe (pipe from 1.8+ deprecated)
● noticeable in the case of error handling
Thank you
Code showcase
Discussion
then
Images used in presentation
● Callback mem
http://i.imgur.com/dHCqj.jpg
● Thank you image http://media.tumblr.
com/cda999f9eb5857ea62323368f1a94577/tumblr_inline_misrk5wRf81qz4rgp.gif
● jQuery logo
http://upload.wikimedia.org/wikipedia/en/9/9e/JQuery_logo.svg
● Dojo logo
http://www.socialseomanagement.com/sites/default/files/dojo.png
● Ajax can http://www.walgreens.com/dbimagecache/03500005360_450x450_a.jpg?
01AD=3L88KEUeA9XexrvKpx8FNgPIx6lu4gfXFVidRMbWTJqGPihxbA-
UDiQ&01RI=71DA49E5EE1856F&01NA=
Links from presentation
● CommonJS Promises / A spec
http://wiki.commonjs.org/wiki/Promises/A
http://wiki.commonjs.org/wiki/Promises/A
● Ksis Zyp Github
https://github.com/kriszyp
● Q.js library (github)
https://github.com/kriskowal/q
● Future's js (github)
https://github.com/coolaj86/futures
● jQuery Deferred API
http://api.jquery.com/category/deferred-object/
● Promises libraries perf test
https://github.com/cujojs/promise-perf-tests