O'Reilly

Dojo DeferredList

By on  

Deferreds are all the rage in the JavaScript community these days and who can argue?  Deferreds, an object representing an asynchronous action, make working with AJAX requests incredibly easy -- no callback hell, no problem passing request information around.  What if you want to work with multiple Deferreds though?   For example, say you want to execute functionality once multiple AJAX requests complete.  The Dojo Toolkit has you covered with dojo/DeferredList, a resource whose API mirrors a single Deferred object but is capable of handling multiple Deferreds.

Using Deferreds

Dojo returns Deferred objects from many operations, including animation and XHR requests.  With the Deferred object, you can use the then property to react to the response once the async interaction is completed:

// A very basic usage of dojo/request
request("service.php?id=someid").then(function(response) {
	console.log("request result is:", response);
});

The example above shows a basic AJAX request and handling of the resulting Deferred.  Easy, right?  But what if you want an action to execute only after multiple Deferreds have resolved?

Using dojo/DeferredList

The DeferredList is a manager for multiple Deferreds, making handling multiple Deferreds a breeze:

// Require the Dojo dependencies
require(["dojo/request", "dojo/DeferredList"], function(request, DeferredList) {
	console.log("Request loaded!", request);

	// Request 1
	var promise1 = request("/endpoint/1").then(function(response) {
		console.log("request 1 result", response);
	});

	// Request 2
	var promise2 = request("/endpoint/2").then(function(response) {
		console.log("request 2 result", response);
	});

	// Create a DeferredList to manage both of them
	var list = new DeferredList([promise1, promise2]);
	// When they're both resolved...
	list.then(function(result) {
		// result is:  [Array[2], Array[2]]
		// result item[0] is the result of each request

		// Do something!
		
	});
});

The example above represents all roses:  all successful Deferreds.  What if a Deferred fails;  a 404 error, request timeout, or a Deferred rejection?  A little validation cures all that:

// Require the Dojo dependencies
require(["dojo/request", "dojo/DeferredList"], function(request, DeferredList) {
	console.log("Request loaded!", request);

	// Request 1
	var promise1 = request("/endpoint/1").then(function(response) {
		console.log("request 1 result", response);
	});

	// Request 2
	var promise2 = request("/endpoint/2").then(function(response) {
		console.log("request 2 result", response);
	});

	// Request 3:  A request that will fail...
	var promise3 = request("/endpoint/noexist").then(function(response) {
		console.log("request 3 result (fail)", response);
	});

	// Create a DeferredList to manage both of them
	var list = new DeferredList([promise1, promise2, promise3]);
	// When they're both resolved...
	list.then(function(result) {
		if(request[0][0] && request[1][0] && request[2][0]) { // request[2][0] is false
			// Success!
		}
		else {
			// React to a failure
		}
	});
});

If the promise for a given Deferreds returns false, you know the request (or async action) failed.  The second argument returned by the Deferred provides information about the request and why it failed:

{
	"message": "Unable to load noexist.php status: 404",
	"response": {
		"url": "/endpoint/noexist",
		"options": {
			"headers":{}
		},
		"xhr": {
			"statusText": "Not Found",
			"status": 404,
			"response": "{404 page html}"}
		}
}

The example here is oversimplified.  One realistic example is the one I used to create the dojox/mobile TweetView example, sending multiple JSONP requests (Twitter profile and Twitter timeline list) for a client-side Twitter widget.  The dojo/DeferredList resource makes handling multiple asynchronous actions easy and enjoyable.  Just another reasons to use the Dojo Toolkit in your next web application!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

  • LightFace:  Facebook Lightbox for MooTools

    One of the web components I've always loved has been Facebook's modal dialog.  This "lightbox" isn't like others:  no dark overlay, no obnoxious animating to size, and it doesn't try to do "too much."  With Facebook's dialog in mind, I've created LightFace:  a Facebook lightbox...

  • An Interview with Eric Meyer

    Your early CSS books were instrumental in pushing my love for front end technologies. What was it about CSS that you fell in love with and drove you to write about it? At first blush, it was the simplicity of it as compared to the table-and-spacer...

Incredible Demos

  • Optimize Your Links For Print Using CSS â Show The URL

    When moving around from page to page in your trusty browser, you get the benefit of hovering over links and viewing the link's target URL in the status bar. When it comes to page printouts, however, this obviously isn't an option. Most website printouts...

  • Create Twitter-Style Buttons with the Dojo Toolkit

    I love that JavaScript toolkits make enhancing web pages incredibly easy. Today I'll cover an effect that I've already coded with MooTools: creating a Twitter-style animated "Sign In" button. Check out this five minute tutorial so you can take your static...

Discussion

  1. Be sure to check out dojo/promise/all in 1.8:

    all([def1, def2]).then(function(results){
        // results[0], results[1]
    });
    
    • I like that DeferredList is backward-compatible and better documented :)

  2. Markus

    jQuery’s $.when() does the same job, but the api looks more intuitiv

  3. Cesar

    Is there any way to learn Dojo that isn’t a pain in the back? I’m trying and I have quite a bit of experience on other libraries, but Dojo does things in such a crazy way (or the docs are really bad at explaining things), for example, I still can’t understand why make such a huge change just to avoid global scope, after all, if you just use Dojo, you won’t have name conflicts (and even then you can just use dojo.blahblah).

    Sorry if this looks like I’m against Dojo, I’m not, in fact I’m trying to migrate from Mootools, but besides being “the more correct way to code” (which many have claimed and I still think it’s quite subjective) I’m starting to think there isn’t a worthy reason to go through all the pain of learning Dojo, yes, and I will say it again it’s a pain even with the good will to learn it, I’m having such a heavy complain because I didn’t have this problem moving from JQuery to Mootools which, both are a “import/customize the file, use whatever you need, learn as you need”, you don’t have to learn to code again, you just have to use the libraries (though Mootools it’s more suitable for large projects because it’s more organized).

    I’ve been following your blog since quite some time and I would like to know your opinion about this (and a possible solution).

    • Skullcap

      I agree with Cesar. I have been trying to be efficient at working with dojo and dijit for 6 months (!)… and I still feel like an idiot with it. Maybe I am an idiot, I have never had this problem with any other framework/toolkit/api… Dojo leaves me scratching my head every fricking day. Dojo.core seems elegant, logical and straight forward to use. But dijit!! Oh my. Oh my oh my. I want to curl up into a ball and suck my thumb whenever I have to work on widgets or even worse, style my widgets (sadly, this is daily for the past few months; my thumb is quite raw by now). Look at me, I am ranting instead of working on my widgets.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...