Login Register Help
API Documentation
Choose a stylesheet:

Constructordojo.Deferred

<script src="path/to/dojo.js"></script>
defined in dojo/_base/Deferred.js

JavaScript has no threads, and even if it did, threads are hard. Deferreds are a way of abstracting non-blocking events, such as the final response to an XMLHttpRequest. Deferreds create a promise to return a response a some point in the future and an easy way to register your interest in receiving that response.

The most important methods for Deffered users are:

  • addCallback(handler)
  • addErrback(handler)
  • callback(result)
  • errback(result)

In general, when a function returns a Deferred, users then “fill in” the second half of the contract by registering callbacks and error handlers. You may register as many callback and errback handlers as you like and they will be executed in the order registered when a result is provided. Usually this result is provided as the result of an asynchronous operation. The code “managing” the Deferred (the code that made the promise to provide an answer later) will use the callback() and errback() methods to communicate with registered listeners about the result of the operation. At this time, all registered result handlers are called with the most recent result value.

Deferred callback handlers are treated as a chain, and each item in the chain is required to return a value that will be fed into successive handlers. The most minimal callback may be registered like this:

var d = new dojo.Deferred();
d.addCallback(function(result){ return result; });

Perhaps the most common mistake when first using Deferreds is to forget to return a value (in most cases, the value you were passed).

The sequence of callbacks is internally represented as a list of 2-tuples containing the callback/errback pair. For example, the following call sequence:

var d = new dojo.Deferred();
d.addCallback(myCallback);
d.addErrback(myErrback);
d.addBoth(myBoth);
d.addCallbacks(myCallback, myErrback);

is translated into a Deferred with the following internal representation:

[
    [myCallback, null],
    [null, myErrback],
    [myBoth, myBoth],
    [myCallback, myErrback]
]

The Deferred also keeps track of its current status (fired). Its status may be one of three things:

  • -1: no value yet (initial condition)
  • 0: success
  • 1: error

A Deferred will be in the error state if one of the following three conditions are met:

  1. The result given to callback or errback is “instanceof” Error
  2. The previous callback or errback raised an exception while executing
  3. The previous callback or errback returned a value “instanceof” Error

Otherwise, the Deferred will be in the success state. The state of the Deferred determines the next element in the callback sequence to run.

When a callback or errback occurs with the example deferred chain, something equivalent to the following will happen (imagine that exceptions are caught and returned):

// d.callback(result) or d.errback(result)
if(!(result instanceof Error)){
    result = myCallback(result);
}
if(result instanceof Error){
    result = myErrback(result);
}
result = myBoth(result);
if(result instanceof Error){
    result = myErrback(result);
}else{
    result = myCallback(result);
}

The result is then stored away in case another step is added to the callback sequence. Since the Deferred already has a value available, any new callbacks added will be called immediately.

There are two other “advanced” details about this implementation that are useful:

Callbacks are allowed to return Deferred instances themselves, so you can build complicated sequences of events with ease.

The creator of the Deferred may specify a canceller. The canceller is a function that will be called if Deferred.cancel is called before the Deferred fires. You can use this to implement clean aborting of an XMLHttpRequest, etc. Note that cancel will fire the deferred with a CancelledError (unless your canceller returns another kind of error), so the errbacks should be prepared to handle that error for cancellable Deferreds.

Usage

var foo=new dojo.Deferred(canceller: Function?); (view source)
parametertypedescription
cancellerFunctionOptional.

Examples

Example 1

var deferred = new dojo.Deferred(); setTimeout(function(){ deferred.callback({success: true}); }, 1000); return deferred;

Example 2

Deferred objects are often used when making code asynchronous. It may be easiest to write functions in a synchronous manner and then split code using a deferred to trigger a response to a long-lived operation. For example, instead of register a callback function to denote when a rendering operation completes, the function can simply return a deferred:

// callback style:
function renderLotsOfData(data, callback){
    var success = false
    try{
        for(var x in data){
            renderDataitem(data[x]);
        }
        success = true;
    }catch(e){ }
    if(callback){
        callback(success);
    }
}
 
// using callback style
renderLotsOfData(someDataObj, function(success){
    // handles success or failure
    if(!success){
        promptUserToRecover();
    }
});
// NOTE: no way to add another callback here!!

Example 3

Using a Deferred doesn’t simplify the sending code any, but it provides a standard interface for callers and senders alike, providing both with a simple way to service multiple callbacks for an operation and freeing both sides from worrying about details such as “did this get called already?”. With Deferreds, new callbacks can be added at any time.

// Deferred style:
function renderLotsOfData(data){
    var d = new dojo.Deferred();
    try{
        for(var x in data){
            renderDataitem(data[x]);
        }
        d.callback(true);
    }catch(e){
        d.errback(new Error("rendering failed"));
    }
    return d;
}
 
// using Deferred style
renderLotsOfData(someDataObj).addErrback(function(){
    promptUserToRecover();
});
// NOTE: addErrback and addCallback both return the Deferred
// again, so we could chain adding callbacks or save the
// deferred for later should we need to be notified again.

Example 4

In this example, renderLotsOfData is syncrhonous and so both versions are pretty artificial. Putting the data display on a timeout helps show why Deferreds rock:

// Deferred style and async func
function renderLotsOfData(data){
    var d = new dojo.Deferred();
    setTimeout(function(){
        try{
            for(var x in data){
                renderDataitem(data[x]);
            }
            d.callback(true);
        }catch(e){
            d.errback(new Error("rendering failed"));
        }
    }, 100);
    return d;
}
 
// using Deferred style
renderLotsOfData(someDataObj).addErrback(function(){
    promptUserToRecover();
});

Note that the caller doesn’t have to change his code at all to handle the asynchronous case.

Jump to PropertiesFunctionsBack to top

Add the same function as both a callback and an errback as the next element on the callback sequence.This is useful for code that you want to guarantee to run, e.g. a finalizer.
Add a single callback to the end of the callback sequence.
FunctionaddCallbacks(cb, eb)
Add separate callback and errback to the end of the callback sequence.
FunctionaddErrback(cb, cbfn)
Add a single callback to the end of the callback sequence.
Functioncallback(res)
Begin the callback sequence with a non-error value.
Cancels a Deferred that has not yet received a value, or is waiting on another Deferred as its value.
Functionerrback(res: Error)
Begin the callback sequence with an error result.
Used internally to exhaust the callback sequence when a result is available.
Function_resback(res)
The private primitive that means either callback or errback

Jump to FunctionsPropertiesBack to top

Navigating the Dojo API Tool

There are several different methods of navigating through the object structure of the Dojo Toolkit:

  • Use the namespace list (to the left). The simplest method would be to use the list of namespaces defined by the Dojo Toolkit, on the left side of every page.
  • Drill-down from where you are. The API Tool was designed to give you as much information via drill-down as possible. Everything defined in an object can be clicked on, for more information.
  • Use the search. At the top of the namespace list to the left is a search box; type in the terms you are looking for, and you will be taken to a result page that spans the entire toolkit.
Move to different sections

In addition, objects with large numbers of contained types have a simple way of jumping to sections on a page; simply look at the right side of any heading, and you will see a set of quick navigation icons. Clicking a type icon will take you to that section; clicking the up arrow icon will return you to the top of the page.

Inherited and private members

Show or hide variable types

The Dojo API Tool will show the full ancestry of an object's members (including how that member was defined and whether or not it overrides an original). By default, all members of an object that are inherited are shown with the object's API listing, and all private members are hidden.

To toggle either inherited or private members, look just beneath the breadcrumb bar (above the name of the object you are viewing) and click the appropriate link.

Switching styles

Choose a style

The Dojo API Tool was designed with several themes in mind; we know that some people prefer light on dark, while others might prefer dark on light. With this in mind, two themes (Noir and Blanc) are currently available, with more on the way.

To switch visual styles, click on the theme you want to use, near the top right corner of the page. The API Tool will remember which style you prefer and automatically load that theme on subsequent visits.

Key/Legend

Namespace Namespaces
A namespace in Dojo parlance is an object/property bag that can contain almost anything: constructors, methods, properties, etc. Usually is expressly defined to serve a particular purpose; for example, dojo.date.locale is a namespace defined to deal with locale-specific date handling.
Constructor Constructors
A constructor is a function designed to create instances of objects. With the Dojo Toolkit, there are two ways of creating constructors: the "old school" way (i.e. defining a function with the this keyword in the body) or using dojo.declare.
Singleton Singletons
A singleton is a constructor that is defined and then immediately executed so that only one instance may ever exist during an application's lifetime. Usually this is done to capture some information in the environment, or to ensure a set of private variables that cannot be accessed from outside of the declaration. Examples include dojox.encoding.crypto.Blowfish.

Data Types

Array Array
Arrays are ordered lists, native to Javascript.
Boolean Boolean
Native data type representing a simple "true/false" value.
Date Date
Native Javascript data type to handle common date and time representations.
DOMNode Node
An object that represents any kind of element being referenced/used by Javascript code. Note that the type of element is not dictated by this data type; only that it is a node of some sort.
Error Error
A special, native Javascript object used to indicate an error in code. Can be subclassed and used in conjunction with the throw statement, i.e. throw new MySubError(...);
Function Function
Functions/methods are pieces of invocable code; in JavaScript, they are also considered data and can be passed around like any other object.
Number Number
A Number object is used to represent any kind of numeric value; note that Javascript does not guarentee the actual underlying datatype (though the most common is a 64-bit float).
Object Object
Objects are the base data type of Javascript. With the Dojo API Tool, a type that cannot be determined is usually marked with this icon, in addition to straight objects.
Regular Expression RegExp (Regular Expression)
A regular expression is an object used for fast string search and parsing.
String String
A string is any sequence of characters.

Input formats

  • Filtered HTML:
    • Web page addresses and e-mail addresses turn into links automatically.
    • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>

      This site allows HTML content. While learning all of HTML may feel intimidating, learning how to use a very small number of the most basic HTML "tags" is very easy.

      For more information see W3C's HTML Specifications or use your favorite search engine to find other sites that explain HTML.

      Most unusual characters can be directly entered without any problems.

      If you do encounter problems, try using HTML character entities. A common example looks like &amp; for an ampersand & character. For a full list of entities see HTML's entities page.

    • Lines and paragraphs are automatically recognized. The <br /> line break, <p> paragraph and </p> close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple blank lines.
  • PHP code:
    • Using custom PHP code

      If you know how to script in PHP, Drupal gives you the power to embed any script you like. It will be executed when the page is viewed and dynamically embedded into the page. This gives you amazing flexibility and power, but of course with that comes danger and insecurity if you do not write good code. If you are not familiar with PHP, SQL or with the site engine, avoid experimenting with PHP because you can corrupt your database or render your site insecure or even unusable! If you do not plan to do fancy stuff with your content then you are probably better off with straight HTML.

      Remember that the code within each PHP item must be valid PHP code - including things like correctly terminating statements with a semicolon. It is highly recommended that you develop your code separately using a simple test script on top of a test database before migrating to your production environment.

      Notes:

      • You can use global variables, such as configuration parameters, within the scope of your PHP code but remember that global variables which have been given values in your code will retain these values in the engine afterwards.
      • register_globals is now set to off by default. If you need form information you need to get it from the "superglobals" $_POST, $_GET, etc.
      • You can either use the print or return statement to output the actual content for your item.

      A basic example:

      You want to have a box with the title "Welcome" that you use to greet your visitors. The content for this box could be created by going:

      print t("Welcome visitor, ... welcome message goes here ...");
      								

      If we are however dealing with a registered user, we can customize the message by using:

      global $user;
      if ($user->uid) {
      	print t("Welcome $user->name, ... welcome message goes here ...");
      }
      else {
      	print t("Welcome visitor, ... welcome message goes here ...");
      }
      								

      For more in-depth examples, we recommend that you check the existing Drupal code and use it as a starting point, especially for sidebar boxes.

  • Full HTML:
    • Web page addresses and e-mail addresses turn into links automatically.
    • Lines and paragraphs are automatically recognized. The <br /> line break, <p> paragraph and </p> close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple blank lines.
  • Markdown:
    • Quick Tips:
      • Two or more spaces at a line's end = Line break
      • Double returns = Paragraph
      • *Single asterisks* or _single underscores_ = Emphasis
      • **Double** or __double__ = Strong
      • This is [a link](http://the.link.com "The optional title text")
      For complete details on the Markdown syntax, see the Markdown documentation.