jQuery, Promises & Deferred
jQuery, Promises & Deferred
Written by Ian Elliot   
Monday, 17 September 2012
Article Index
jQuery, Promises & Deferred
Chaining and Combining Promises


Chaining Promises 

If you want to perform two asynchronous tasks, one after the other, you can by simply chaining then method calls. As in all function chaining to make it work you have to return the correct sort of object from each function.

In many ways this idea is key to understanding and using promises in more sophisticated ways.

To understand what is going on we need to master one subtle point of the way promises work. The then method always returns a promise object. You can think of this as a default object returned to make sure you can always chain calls on the then function. The default promise has as its value  the value returned by the onComplete function of the original promise object.

For example:

var myPromise = $.get("TextFile.txt");
  .then(function (value) {
          return "Hello";
 .then(function (value) {


Now if you run this you will see  "Hello" displayed in the console. Notice the way that the first onComplete function returns "Hello" which is the value of the default promise object returned by then. Also notice that is default promise object is immediately resolved and its onComplete function is executed at once.

What if the first onComplete function was another slow operation?

In this case it should return a promise object so that the UI thread could get on with other things. If you arrange for the onComplete function to return this promise object then it replaces the default promise object for chaining purposes and its value is whatever the onComplete task returns.

For example, suppose we need to download two files one after the other, we might use:

var myPromise = $.get("TextFile1.txt");
  .then(function (value) {
    return $.get("TextFile2.txt");
  .then(function (value) {

In this case the first promise object's then function runs the onComplete function when TextFile1 has finished loading. The onComplete function uses another get to download a second file and returns its promise object.

Notice that, even though the onComplete function has returned, the task it started is still running. The second use of  the then method runs an onComplete function when "TextFile2.txt" has downloaded.

Of course, you might well want to download both files at the same time, but if you care about the order of downloading and need the first file to finish downloading before the second even starts, this is the way to do it.

Chaining promises is a fundamental way to order asynchronous tasks.

This is to be preferred to nested promises e.g.:

var myPromise = $.get("TextFile1.txt");
 function (value) {
     function (value) {


This nests a callback within a callback. It is better to return the promise object and write things like:


and so on.

Combining Promises

If you have a set of asynchronous tasks that occur one after the other then you need to chain together their promise objects.

However, it is more common to have a set of asynchronous tasks that you want to set running, in parallel if possible, and then do something after they have all completed. In this case what you really need to do is join or combine all the promise objects together into one promise object that is resolved only when all of the original promise objects are resolved.

You can combine promises in this way using the when method. If you specify a list of promise objects in the call to when it returns a single "master" promise object that is only resolved when all of the parameter promise objects are resolved.

The onComplete of the master promise object is passed all of the values that the parameter promise objects return.

If any of the parameter promise objects fail and are rejected then the master promise object fails. This means you could have some promise objects that are still working when the master promise object fails.

As a simple example consider downloading two files:

var myPromise1 = $.get("TextFile1.txt");
var myPromise2 = $.get("TextFile2.txt");
myTotalPromise = $.when(myPromise1, myPromise2); myTotalPromise.then(
 function (value1,value2) {


If you run this example you will discover that the two values returned by myPromise1 and mPromise2 are complete objects with all of the values returned by each promise - this is general behavior for the when method.

Notice also that you may well have to keep references to the promises that have been combined so that you can clean up after any tasks that fail. The general rule is that asynchronous processes are much harder to deal with when one fails than when they all work.

Other Promise Methods

Most of the time you can get the job done using just the then method of the promise object but jQuery does provide some extras.

Instead of using the then method to define what should happen you can use the done, fail or always methods to add functions to the promise object which are carried out when the task is complete, fails or when the task completes or fails. 

For example the previous example could be written:

var myPromise = $.get("TextFile.txt"); myPromise.done(
 function (value) {


All three functions can accept any number of functions, or an array of functions, to execute when the promise is resolved. All of the promise methods return a promise so you can chain them and write things like:

 var myPromise = $.get("TextFile.txt")
             .done(function (value) {
                      console.log(value); })

It is up to you to decide on the style that you want to use, but it is worth adding that the then method is the more standard approach to promises. 

jQuery also provides another promise method that is better to avoid if you can. The pipe method lets you add functions or "filters" that can modify the return value of the promise. You can specify a filter for the successful completion, error or progress actions. In each case the filter is called with the value of the promise, it can modify the value and return it to be processed further by the onComplete, error or progress functions. This might be useful in some situations, but it is a facility that is very easy to misuse and you can create programs that are very difficult to debug using it.

Finally the state function can be used to discover the state of a promise - pending, resolved or rejected.

The Deferred Object

I have to confess to a small simplification used throughout the article so far.

jQuery tends to use the Deferred object rather than a promise and it is the Deferred object that is mentioned in the documentation much more than the promise object.

The Deferred object is a promise with some additional methods that enable you to change its state from pending to resolved or rejected and to trigger progress updates.

That is, any Deferred object can be treated as if it was a promise object. Also every Deferred object has a promise method which returns a pure promise object based on the Deferred object.

You use a Deferred object when you are implementing your own asynchronous functions. However, your function may use a Deferred object internally but it should return a promise object to stop other functions from modifying its state.

Some jQuery methods return a Deferred object when they really should return a promise - but you can just treat it as a promise object and restrict yourself to using just then, done, fail etc.

You only really need to know about the Deferred object when you implement your own asynchronous routines that return a promise object, more of which in the second part. 



Chapter List 

  1. The DOM
  2. CSS Selectors
  3. Filters
  4. Advanced Filters
  5. Manipulating The DOM
  6. Promises & Deferred
  7. Promises, Deferred & WebWorkers
  8. Ajax the Basics - get
  9. Ajax the Basic -  post
  10. Ajax - Advanced Ajax To The Server 
  11. Ajax - Advanced Ajax To The Client
  12. Ajax - Advanced Ajax Transports And JSONP
  13. Ajax - Advanced Ajax The jsXHR Object
  14. Ajax - Advanced Ajax Character Coding And Encoding
  15. jQuery - Easy Plugins
  16. jQuery UI
  17. jQuery UI Custom Control - Widget Factory
  18. Getting Started With QUnit Testing

To be informed about new articles on I Programmer, install the I Programmer Toolbar, subscribe to the RSS feed, follow us on, Twitter, Facebook, Google+ or Linkedin,  or sign up for our weekly newsletter.



Getting Started with jQuery UI

jQuery UI is built to work with jQuery. If you are  already using jQuery, it is recommended as an addin to make your pages look like more than just HTML. Let's see how easy it is to get started w [ ... ]

jQuery 3 - Animation

jQuery's animation functions are built on the use of the default function queue. They are easy to use, but can sometimes be confusing because of the way they mix different ways of showing and hiding e [ ... ]

Other Articles




blog comments powered by Disqus



Last Updated ( Tuesday, 25 August 2015 )

Copyright © 2017 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.