Promises (aka Deferred): more efficient handling of async in JavaScript

JavaScript: a mono-threaded language with many asynchronous

JavaScript is a mono-threaded language: it means that at a given time, only one script is being executed but a lot of things are asynchronous: you call a function that has to do some work and that function returns immediately. The best example would be the ajax calls: you send the request, and the browser returns immediately, executing what’s next on the stack. Once the result is received, JavaScript usually calls back a function you supplied

In this very simple jQuery example, we are making an ajax call to get the result of /myContent.html file. Once we get a response, we append the received html to the #myDiv DOM element. Quite simple hey ? Now what if we want to make two calls: call1 and call2 and display an error if any of the calls produce an error. We could write this kind of code:

This works but the problem is that the error would be displayed twice. We could of course check for the error by setting a boolean variable, but still, this wouldn’t be the best way to describe this behavior.

Promises to the rescue

A promise represents the value of an async operation. A promise can have the following three states:

– resolved
– rejected
– pending

Using jQuery’s implementation of the promises – called Deferred -. jQuery already makes use of promises for Ajax calls, so a simple Ajax call could be handled this way:

At first glance, this doesn’t look so much better than the first piece of code, right ? Well, the good thing about the promises, is that we may store the promise for later use and even chain them. Now let’s have a look at the previous piece of code. Using the promises we could write it like this:

Now checking that both ajax calls were successfull would be a matter of checking that both promises have been fullfilled:

Filtered promises

Let’s imagine you want to call two ajax calls, but that you need data from the first call to make the second call, with that data. This is made easy with the promises:

var promise1 = $.ajax(‘/call1′);