Design, Build and Release

Ramblings of IainJMitchell on C#, Javascript and Software Craftsmanship

Deferred Object in jQuery 1.5

2 comments

Introduction

One of the major new additions to jQuery 1.5 is the Deferred Object. This is a feature that is already available in the Dojo Javascript library and is a welcome addition to jQuery functionality.

The predominate use of Deferred Objects in jQuery is within the AJAX rewrite, where they are utilised to attach success and failure callbacks ‘on the fly.’ But, it is important to recognise that they are not just part of AJAX, they are a feature in it’s own right that can be used within our own code.

A Flexible Callback Mechanism

Deferred Objects are all about controlling callbacks in a flexible manor. They allow multiple callbacks to be attached and also permit the adding of callback functions after the callback dispatch has been fired.

Creating a Deferred Object

Initialising a new Deferred Object is straightforward:

var deferred = jQuery.Deferred();

You can use the new operator – but this is entirely optional.

Adding Callbacks

There are three types of callbacks that can be attached to a Deferred Object:

  1. .done() – Any functions added via this will be fired if .resolve() is called on the Deferred object.
    deferred.done(function(){
      alert('resolve() called!');
    });
    
  2. .fail() – Functions added to this will be fired if .reject() is called on Deferred object.
    deferred.fail(function(){
      alert('reject() called!');
    });
    
  3. .then() – All of the functions added to this will be called if .resolve() OR .reject() are called.
    deferred.then(function(){
      alert('reject() OR resolve() called!');
    });
    

Firing the Callback Functions

As mentioned in the last section, the Deferred Object has two functions to fire the attached callbacks (I call these trigger functions). The first of these is .resolve() which triggers the .then() and .done() callbacks. Alternatively, we can use the .reject() function which will trigger the .then() and .fail() callbacks. Both of these can accept arguments which will be passed onto the attached functions. For example:

deferred.done(function(message){
  alert('Hello ' + message);
});
deferred.resolve('Dave');

However, we can only call one of these once on our Deferred Object. Any further calls to either of the functions will not trigger the callbacks. So, in this example…

deferred.done(function(message){
  alert('Hello ' + message);
});
deferred.fail(function(){
  alert('Fail');
});
deferred.resolve('Dave'); //alerts
deferred.reject(); //ignores
deferred.resolve('Hello Hello'); //ignores

..only our ‘Hello Dave’ alert will fire.

Callback Voodoo

Finally, let’s look at the unusual side of the Deferred Object. They actually allow extra callbacks to be added after the Deferred Object .reject() or .resolve() functions have been triggered and if they are relevant they will be immediately called. In this example…

deferred.done(function(message){
  alert('Hello ' + message);
});
deferred.done(function(message){
  alert('Hello again ' + message);
});
deferred.resolve('Dave'); //alerts 'Hello Dave' and 'Hello again Dave'
deferred.done(function(message){
  alert('Goodbye ' + message);
}); //immediately alerts 'Goodbye Dave'

..both alerts are fired, even though the second callback method is added after the .resolve() is fired.

Conclusion

In this article I’ve looked at the new Deferred Object in jQuery 1.5. We’ve seen how you can attach three different types of callbacks and these can be fired by the use of the .resolve() and .reject() trigger functions on the object. These triggers can take optional arguments that will be passed to the callback functions.

Only one trigger can be fired once on each Deferred Object, any subsequent calls to either trigger function will be ignored. However, we can add extra callbacks after the trigger has be fired and this will be immediately called.

Finally, to help make sense of it all, I have added an example of Deferred Objects in action to JsFiddle here.

Written by IainJMitchell

February 8th, 2011 at 8:47 am

Posted in Uncategorized

Tagged with ,

2 Responses to 'Deferred Object in jQuery 1.5'

Subscribe to comments with RSS or TrackBack to 'Deferred Object in jQuery 1.5'.

  1. Great article, apart from the ajax examples of this code, where else might this method be used?

    Mark Kellett

    8 Feb 11 at 10:19 am

  2. I guess any time you need late binding of callbacks or if you need to attach multiple callbacks to a function. Though I think this will be seen more in user defined plugins/widgets rather than floating around in script code.

    IainJMitchell

    8 Feb 11 at 3:13 pm

Leave a Reply