JavaScript Promises

Posted by Shawn Wildermuth on Aug 03, 2013 on 17:59PM

pinky-promiseNo I am not talking the promise that JavaScript will fix everything if you use it. I don't even believe that ;) I am talking about the concept of a promise object that several JavaScript libraries use (including AngularJS, jQuery, Dojo and WinJS).

A promise is a pattern for handling asynchronous operations. The problem is that essentially when you start an asynchronous operation, you need to execute some code as the operation is completed. Asynchronous code is so common that most libraries have found a solution for passing in callbacks. But there is little commonality to how each libraries does this. Let's take jQuery as an example:

In this example you can see the jQuery uses the success property of the settings object to specify the callback. This isn't a promise but a way to pass in the callback functions. When the ajax call is complete, it calls the success function. Depending on the library that uses asynchronous operations, you might pass in a set of callbacks (e.g. for success or failure). There are a ton of ways to accomplish this.

The promise pattern sets out to simplify this process. The asynchronous operation simply returns an object called a promise. The promise allows you to call a method called then that let's you specify the function(s) to use as the callbacks. Let's see how to consume a promise using jQuery as an example:

What is interesting here, is that the object that ajax returns is the xhr object which implements the promise pattern so we can call then as seen here. The power of the call to then is that you can chain them by calling then for discrete operations and completing the operation with a call to done as shown here:

Because many libraries are starting to take on the promise pattern, handling asynchronous operations should be easier no matter what code you're writing (e.g. NodeJS, in-browser JS, etc.). But what does a promise look like from the other side?

One important key to the pattern is that the then function can accept two functions. The first is for the success callback; the second for the failure callback like so:

Notice that in jQuery we're using a call to always to specify that we want to be called whether the success or failure was called.

Let's see how using a promise looks. Here is an example from AngularJS:

AngularJS uses an implementation (see the $q variable) that is started with a call to defer().  This returns an object that contains ways to mark a successful or failure condition as well as the promise itself. Notice that in the _callMe function the d variable is created by calling $q.defer() then the d.promise is returned from the function so that the caller can call the promise methods (e.g. then). When the actual asynchronous operation is performed (in this case mocked up as a setTimeout call), we can use the resolve method on the defer'd object to tell the promise that we completed successfully (and therefore call the first function in the then method below). If we were to call reject, the second method (the failure call) would be called instead.

You can play with these examples in JSFiddle and see what you can make happen. Promises are a really simple and cool way to handle asynchronicity. What I really like about it is that it simplifies your code (so that you don't have the triangle of doom when you have to nest callback functions inside each other. This makes it easy.

Application Name WilderBlog Environment Name Production
Application Ver Runtime Framework .NETCoreApp,Version=v1.0
App Path D:\home\site\wwwroot Runtime Version .NET Core
Operating System Microsoft Windows 6.2.9200 Runtime Arch X86