jQuery Deferred and Promise for sequential execution of synchronous and asynchronous functions
Solution 1
For jQuery prior to 1.8, this is a problem, but for new versions of jQuery, this is not a problem anymore:
function test(){
var d = jQuery.Deferred(),
p=d.promise();
//You can chain jQuery promises using .then
p.then(a).then(b).then(c);
d.resolve();
}
test();
Below is the demo of jQuery 1.7.2
Solution 2
jQuery < 1.8 is fine WRT chaining, you just use .pipe
instead of .then
. 1.8 simply changed .then
to be .pipe
.
Solution 3
Sidenote: When you use it without the array, you don't have to start with a promise. $.when({}).then(a).then(b)
will do the trick just fine. You only need to make sure you don't put a
inside the when
.
Related videos on Youtube
HMR
Like programming because interest me. Love getting paid for my hobby. I am available for mentoring, just send a message to harmmeiier at the gmail com.
Updated on July 09, 2022Comments
-
HMR almost 2 years
If I want to have synchronous and asynchronous functions execute in a particular order I could use jQuery promise but it doesn't seem to work the way I'd expect it to work.
Functions a,b and c should execute in that order when in a the
deferred.resolve()
is called I'd expect function b to be executed but all functions are executed immediately no matter if the resolve is called.Here is the code:
function a(){ var deferred = $.Deferred(); setTimeout(function(){ console.log("status in a:",deferred.state()); //this should trigger calling a or not? deferred.resolve("from a"); },200); console.log("a"); return deferred.promise(); }; function b(){ var deferred = $.Deferred(); setTimeout(function(){ console.log("status in b:",deferred.state()); deferred.resolve("from b"); },200); console.log("b"); return deferred.promise(); } //synchronous function function c(){ var deferred = $.Deferred(); console.log("c"); console.log("status in c:",deferred.state()); deferred.resolve("from c"); return deferred.promise(); } function test(){ fn=[a,b,c],i=-1, len = fn.length,d, d = jQuery.Deferred(), p=d.promise(); while(++i<len){ p=p.then(fn[i]); } p.then(function(){ console.log("done"); }, function(){ console.log("Failed"); }); d.resolve(); //instead of the loop doing the following has the same output //p.then(a).then(b).then(c); //d.resolve(); } test();
Output is:
a b status in c: pending c done status in a: pending status in b: pending
Expected output:
a status in a: pending b status in b: pending c status in c: pending done
Tried a some combinations of the following modifications:
d = jQuery.Deferred(); setTimeout(function(){d.resolve();},100); var p=d.promise(); while(++i<len){ p.then(fn[i]); }
But all with same unexpected results, b gets called before deferred of a is resolved, c is called before deferred of b is resolved.
-
A. Wolff over 10 yearsAs a side note, to get it works in jquery 1.7.2 (using extend jq native code) jsfiddle.net/L5nud/2
-
Esailija over 10 yearsjQuery < 1.8 is fine WRT chaining, you just use .pipe instead of .then. 1.8 simply changed .then to be .pipe.
-
Cristian almost 10 yearshow to use it, if
a
function return a value that useb
function and so on. -
Khanh TO almost 10 years@Cristian Chaparro A. The returned value of
a
function is passed as an argument tob
function.