Chaining jQuery.Deferred

A small jQuery extension to add deferred chaining with example.

JavaScript

// jQuery 1.6 is adding similar functionality

// Since we are creating a new deferred object every time we chain we don't have to worry 
//  about someone calling a none promise function, such as resolved, on the original deferred.

(function($) {
  function deferred_chain(next) {
    var dfd = new $.Deferred();
    this.done(function() {
      var dfd_next = next.apply(this, arguments);
      dfd_next.done(dfd.resolve);
    });
    return dfd;
  }
      
  var base = $._Deferred;
  
  $._Deferred = function() {
    var dfd = base();
    dfd.chain = deferred_chain;
    return dfd;
  };
})(jQuery);

//Example: We want to construct a message "ABC" from three asynchronous messages ("A", "B", "C")

var asyncMessage = function(msg) {
  var dfd = new $.Deferred();
  setTimeout(function() { dfd.resolve(msg); }, 100);
  return dfd;
};

//this is required for Chrome (not tested in other browsers)
function log(m) { console.log.apply(console, [m]); };

asyncMessage("Chained:A")
  .chain(function(m) { return asyncMessage(m + "B"); })
  .chain(function(m) { return asyncMessage(m + "C"); })
  .done(log); // -> outputs "Chained:ABC"