# The Promise of jQuery Deferred
19th April 2013 — [jQuery UK](http://events.jquery.org/2013/uk/)
## Tale Of A UK Job Application
### *And Pardon my French*
1. Submitting an application form
1. Being shortlisted
1. Phone Interview
1. Technical Interview
1. Physical Interview
1. Salary Negociation
Then, **accept the contract and relocate** or …
@@@
## Let's translate that in JavaScript…
@@@
```javascript
(function jobApplication(){
(function shortlist(data){
(function phoneInterview(){
(function technicalInterview(data){
(function physicalInterview(){
(function salaryNegociation(payload){
if (payload.job){
acceptContract() && relocate();
}
else throw SyntaxError("Too bad…");
})({ job: "Software Engineer" });
})();
})({ script: "eval('alert(true);')" });
})();
})({ why: "I speak JavaScript!" });
})();
```
@@@
## Badge Unlocked: *Pyramid* of Doom!
![](images/doom.jpg)
@@@
## Promisification!
@@@
```javascript
var $job = $.Deferred();
$jobApplication
.progress( updateApplicationState )
.done( acceptContract )
.done( relocate )
.fail( keepCalmAndDrinkWine );
$jobApplication
.notify({ state: "shortlist" })
.notify({ state: "phone_interview" })
.notify({ state: "technical_interview" })
.notify({ state: "physical_interview" })
.notify({ state: "salary_negociation" });
$jobApplication.resolve({
job: "Software Engineer"
});
```
[See on JSBin](http://jsbin.com/episez/6/edit).
![](../../img/avatar.jpg)
## Thomas Parisot
Frontend / JavaScript Engineer
[![BBC R&D](../../img/RD-logo_500.png)](http://www.bbc.co.uk/rd)
[thom4.net](https://thom4.net) –
[@thom4parisot](https://twitter.com/thom4parisot) –
[github.com/thom4parisot](https://github.com/thom4parisot)
## Digging into jQuery.Deferred
Learning to use Promises, the soft way.
@@@
## Consume the API
In jQuery 1.8+: `$.ajax`, `$.animate`, `$('')`
```javascript
var $deferred = $.post('/cheese', {
name: "Livarot"
});
$deferred
.done( syncLocalStorage )
.done( updateUI )
.fail( displayError )
.always( logNetworkResponse );
```
@@@
## Create your first Deferred
```javascript
function getDelayedUserInput(){
var $deferred = $.Deferred();
setTimeout(function(){
$deferred.resolve(prompt("Anything to say?"));
}, 1000);
return $deferred;
}
$('input').on('click', function(e){
getDelayedUserInput().done(function(user_input){
$(e.target).val(user_input);
});
});
```
[See on JSBin](http://jsbin.com/ocadol/3/edit).
@@@
## Deal with race condition workflows
* `then()` enables data filtering.
* `when()` is a `done()` for multiple promises.
```javascript
$.when( $.getJSON('/page/1'), $.getJSON('/page/2') )
.then(function(page1_data, page2_data){
return page1_data.concat(page2_data);
})
.done( displayCombinedData )
.fail( displayError );
```
@@@
## Sharing safely your Deferred
`jQuery.Deferred` vs. `Deferred.promise()`.
```javascript
var $deferred = $.Deferred();
var $promise = $deferred.promise();
$promise.done(function(value){
console.log("Oh my "+value);
});
// $promise is read-only
$promise.resolve("gosh");
// will log 'Oh my head'
$deferred.resolve("head");
```
[See on JSBin](http://jsbin.com/uzokam/1/edit).
@@@
## Improving our first Deferred
```javascript
function getDelayedUserInput(){
var $deferred = $.Deferred();
setTimeout(function(){
$deferred.resolve(prompt("Anything to say?"));
}, 1000);
return $deferred.promise(); // now safe
}
$('input').on('click', function(e){
getDelayedUserInput().done(function(user_input){
$(e.target).val(user_input);
});
});
```
[See on JSBin](http://jsbin.com/ocadol/4/edit).
## Tale of a country relocation
Let's use another real life example (that's still better than *Hello world examples*).
1. opening a bank account
1. finding a new place to live
1. request a NINo
1. ask for a debit card
And hope for an on-time payday to finally live like a new settler!
@@@
## Opening a bank account
```javascript
function requestBankAccount(job, postal_address){
var $deferred;
// expect an 'account' object to be resolved
$deferred = $.post('http://bank.com/account', {
job: job,
address: postal_address
});
return $deferred.promise();
}
```
@@@
## Assembling the workflow
Let's assume we have a `$job` promise available in the scope.
```javascript
var $address, $account, $NINo, $debitCard;
$address = requestAppartment(job);
$.when($job, $address).done(function(job, address){
$account = requestBankAccount(job, address);
$NINo = requestNINo(job, address);
$account.done(function(account){
$debitCard = requestDebitCard(account, address);
});
});
```
## Killing the FUD
The Internet told me:
* the Promises are *everything*
* the Promises are *Evil*
@@@
## Callback vs. Promise vs. Event
Callbacks are for *easy* and *simple* uses.
```javascript
nodes.value(function(item){
return item.service_id;
});
```
Events are for vertical code expansion.
```javascript
MyModule.prototype.init = function init(view){
view.$submit.on('click', this.handleSubmit);
view.$document.on('click keyup', this.logEvent);
};
```
@@@
## When to use them?
Some considerations to think about to know when to use Promises.
* simplifying a *workflow contract*
* *flattening* code nesting
* undeterminate duration *async task*
* *coordinating* multiple async tasks
### *tl;dr*: modularize chained tasks.
@@@
## jQuery Deferred is not Promise/A+ compliant
Who cares? As long as it helps you to:
* simplify your code
* keep your code maintainable (for you and your peers)
@@@
## Remember kids
Patterns and tools help to *solve problems*.
**You** solve the *problems*.
FUD solves *nothing*.
## To infinity and beyond!
* [jQuery Deferred API](http://api.jquery.com/category/deferred-object/)
* [CommonJS Promise/A+](https://github.com/promises-aplus)
* [ECMAScript Promises](http://wiki.ecmascript.org/doku.php?id=strawman:concurrency)
* [DOM Future](http://dom.spec.whatwg.org/#futures)
* Libraries: [async](https://github.com/caolan/async),
[ff](https://github.com/gameclosure/ff),
[q](https://github.com/kriskowal/q)
## Thanks everybody
Have a question? Come *talk* / *tweet* / *email* to me.