Promises, Promises

Premasagar Rose, @premasagar, Dharmafly
Aaron Acerboni, @aaronacerboni, School of Life

Async – 9th February, 2012
Slidespromisespromises.dharmafly.com
Repo for demos and slidesgithub.com/premasagar/promisespromises
premasagar.comhalfmelt.com

Use the arrow keys or space on your keyboard to navigate →

Asynchronicity

Make a request...

... wait... (get on with something else)...

... get a response.

Do something with the response.

Ajax, a quick recap

var url = "http://asyncjs.com",
    xhr = new XMLHttpRequest();

xhr.open("GET", url, true);
xhr.onreadystatechange = function(event){
  if (xhr.readyState === 4) { // request complete
    if (xhr.status === 200) { // done
      foo(xhr.responseText);
    }
    else { // fail
      bar(xhr.statusText);
    }
  }
};
xhr.send(null);

Ajax, in jQuery

jQuery.ajax(url, {
  success: function(data){}, // done
  error: function(){}        // fail
});

jQuery has numerous Ajax helper functions, .get(), .getJSON(), .post(), etc.

So far, so good

Multiple requests, tangled mess

If many requests are required, e.g. to render an interface, you get chaos.

Too tightly coupled

var counter = 0, numRequests = 10;

jQuery.ajax(url1, {
  success: function(data){
    counter += 1;
    if (counter === numRequests){
      doSomething1(data);
    }
  },
  error: onError
});

jQuery.ajax(url2, {

  // etc ...

Multiple requests

The promise of Promises

Promises

An object that can be interacted with, while waiting for the result of an action.

May be in one of the 3 states:

  • unfulfilled
  • fulfilled
  • failed

The promise may only move from unfulfilled to fulfilled
or unfulfilled to failed.

then method

then(fulfilledHandler, errorHandler, progressHandler);

jQuery's Ajax methods now return promises

var promise = jQuery.get(url);

promise
  .then(doneCallback1, errorCallback1)
  .then(doneCallback2, errorCallback2)
  .then(doneCallback3, errorCallback3);

You can use them with jQuery's animation too (see later, in the demos).

Make a Promise

jQuery.Deferred() creates deferreds - a superset of promises that control the promise state.

// Create deferred
var deferred = jQuery.Deferred(),
    promise = deferred.promise();

// App modules subscribe to the promise
promise
  .then(fn)
  .then(fn);

// ...later, the deferred completes
if (foo){
  deferred.resolve();
}
else {
  deferred.reject();
}

Report progress

You can also notify a promise of progress.

var deferred = jQuery.Deferred(),
    promise = deferred.promise();

promise.progress(function(colour){
  console.log(colour);
});

deferred
  .notify("red")
  .notify("green")
  .notify("blue");

deferred.resolve();

jQuery.when pools multiple promises

Pool multiple promises together, return a single, master promise.

var deferred1 = jQuery.Deferred(),
    deferred2 = jQuery.Deferred(),
    deferred3 = jQuery.Deferred();

// Pass deferreds or promises to jQuery.when
var masterPromise = jQuery.when(deferred1, deferred2, deferred3);

masterPromise
  .then(foo)
  .then(bar);
  // etc

jQuery.when

If all promises resolve, the master resolves.

If one promise fails, the master fails.

Progress notifications on the promises bubble up to the master.

Demos ☃

Libraries

Reading material

Thank you.

Premasagar Rose, @premasagar, Dharmafly
Aaron Acerboni, @aaronacerboni, School of Life

Async – 9th February, 2012
Slidespromisespromises.dharmafly.com
Repo for demos and slidesgithub.com/premasagar/promisespromises
premasagar.comhalfmelt.com