Reputation: 13
Could anyoune please clarify what's wrong with the code below ( have read a lot of docs and examples, but still got no idea what's going on)
function t() {
var d = $.Deferred();
setTimeout(function(){
d.resolve();
}, 5000);
return d.promise();
}
function test() {
var dd = $.Deferred();
$.ajax("/echo/json/").done(function() {
dd = t();
dd.done(function() { alert(" dd.done inside ajax")});
});
dd.done(function() { alert(" dd.done outside ajax")});
}
test();
the output was (in ~ 5 s):
"dd.done inside ajax:"
Why second .done is not working?
Upvotes: 1
Views: 56
Reputation: 707218
Your second alert is never called because the original deferred you assign to the variable dd
is never resolved and thus its .done()
handler is never called.
You create a deferred and assign it to dd
here:
var dd = $.Deferred();
And, then you set up a .done()
handler with this:
dd.done(function() { alert(" dd.done outside ajax")});
But, when your ajax function finishes, you assign a different promise to the variable dd
with this line:
dd = t();
And, thus nothing ever resolves the original promise so its .done()
handler is never called.
I'd suggest this design instead:
function t() {
var d = $.Deferred();
setTimeout(function(){
d.resolve();
}, 5000);
return d.promise();
}
function test() {
return $.ajax("/echo/json/").then(function() {
console.log("ajax call done");
return t();
}).then(function() {
console.log("after timer");
});
}
test().then(function() {
console.log("everything done");
});
Working demo: http://jsfiddle.net/jfriend00/atafc5hj/
This illustrates the following concepts which are useful to know:
$.ajax()
rather than creating your own..then()
handler to make the sequence wait for that promise too.Upvotes: 0
Reputation: 413702
Let's look at test()
:
function test() {
var dd = $.Deferred();
$.ajax("/echo/json/").done(function() {
dd = t();
dd.done(function() { alert(" dd.done inside ajax")});
});
dd.done(function() { alert(" dd.done outside ajax")});
}
test();
Local variable dd
is initialized to a new jQuery Deferred object. Then, an ajax operation is started, and given a "done" callback that'll call the other test function t()
.
The $.ajax()
call will return essentially immediately, long before its .done()
callback is run. Right after that, another .done()
callback is established for that Deferred instance created at the beginning of the function.
Now, when the ajax "done" callback runs, the value of dd
— the initially-created Deferred object — will be overwritten with the Promise returned from t()
. Eventually that .done()
callback will be run, but nothing ever resolves the first Deferred instance, so that "outside" callback never happens.
Upvotes: 2
Reputation: 144669
Because that deferred object is not resolved. You are creating 2 deferred objects and resolving one of them.
Upvotes: 1