As @Bergi writes, jQuery Deferreds / Promises do not expand by prototype inheritance.
Instead, the model adopted by jQuery should allow individual Promise instances to expand using the syntax:
deferred.promise(target);
By defining a constructor with a set of methods, any jQuery Deferred or Promise can be extended using simple syntax
.promise(Constructor())
In my unpublished undocumented jQuery promises playground, the constructor has the name $P and is stored in the jQuery namespace, so the actual syntax I use is:
.promise($.$P())
You should be aware of this, for the most part, you do not need to explicitly call $.$P() , since the Playground includes the $.when_() method, which returns an already extended promise.
Here's a shortened version of the playground with enough to provide the .delay() method:
(function($) { $.$P = function() { if (this instanceof $.$P) { return this; } else { return new $.$P(); } }; $.$P.prototype.then_ = function(fa, fb) { return this.then(fa||null, fb||null).promise($.$P()); } $.$P.prototype.delay_ = function(ms) { var promise = this; function f(method) { return function() { setTimeout(function(){ method.apply(null,this); }.bind(arguments), ms||0); }; } return $.Deferred(function(dfrd) { promise.then(f(dfrd.resolve), f(dfrd.reject)); }).promise($.$P()); } function consolidate(args) { return Array.prototype.slice.apply(args).reduce(function(arr, current) { return arr.concat(current); }, []); } $.extend({ 'when_': function() { return $.when.apply(null, consolidate(arguments)).promise($.$P()).then_(function() { return consolidate(arguments); }); }, }); })(jQuery);
A full playground also includes a whole bunch of more static and promising methods for other purposes, and their development is the essence of the game.
The basic rules for using Playgound are as follows:
- All static and promising methods for playgrounds end with an underscore "_".
- Static methods, such as
$.when_() , are only available when installing Playgound. - Promises in the promise chain are expanded to include a static method, such as
.when_() , or a chain of .promise($.$P()) . - In the promise chain, extensions remain available (down the chain) using the "..." methods, rather than standard methods such as
.then_() instead of .then() .
So how to use this to impose the delays required by the question:
jQuery(function($) { var MYNAMESPACE = { run: function (t) { return $.when_() .then_(function () { log("call together"); log("call together"); }) .delay_(t) .then_(function () { log("call first"); }) .delay_(t) .then_(function () { log("call second"); }); } } });
Demo
In the demo, the button click handler provides additional guidance on how to use the Playground.
Provisos when using the playground:
- As I said, this is a playground.
- As an adapter for jQuery, not a patch, it is terribly inefficient in various places. The worst aspect is that some methods create an intermediate promise in addition to the one they return.
- Not tested for standards required for use in production code, so use with caution.
And finally, consider only the above if you decide to implement the delay using jQuery. It's much easier to use the lib promise, which already has a .delay() method.