# 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.