Update: this issue was a result of jQuery 1.7 vs 1.8. Do not ever use promises in 1.7 beacuse they aren\'t chainable with returning a promise inside a .then
. 1.8 lo
IMHO, you're not chaining anything. Your 2nd .then
is attached to the same promise as that the first .then
is attached to.
Why?
Notice that, then
will always RETURN the new promise, rather than change the promise it being attached to. It doesn't have side effect.
For example:
var promiseX = promiseA
.then(function() { return promiseB; })
promiseX.then(function() { return promiseC; });
promiseA
won't change its value after being attached then
; it'll keep as is.
promiseX
will be the return value of the 1st then
, that is, promiseB
.
So the 2nd then
is actually attached to promiseB
.
And this is exactly what @Kevin B did in his answer.
Another solution is, since .then
will return the new promise, you can chain the .then
functions like below.
var promiseX = promiseA
.then(function() { return promiseB; })
.then(function() { return promiseC; });
This time, the 1st then
is attached to promiseA
, and guess to which promise is the 2nd then
being attached to?
You're right. It's promiseB
, not promiseA
. Because the 2nd then
is actually being attached to the return value of the 1st then
, i.e., promiseB
.
And finally the 2nd then
's return value is assigned to promiseX
, so promiseX
equals promiseC
.
Ok, get back to the OP's question. The following code is my answer.
var deferred = $.Deferred();
promise = deferred.promise(); // this is the first promise
promise.then(function(){ // callbacks for 1st promise
var t = $.Deferred();
setTimeout(function() {
console.log('rejecting...');
t.reject();
}, 1000);
return t.promise(); // this is the 2nd promise
// return $.Deferred().reject(); // To reject immediately.
}).then(function() { // callbacks for 2nd promise
console.log('i should never be called');
}, function() {
console.log('i should be called');
})
deferred.resolve();
You aren't re-defining the value of promise
, try this:
http://jsfiddle.net/28TDM/1/
var deferred = $.Deferred();
promise = deferred.promise();
promise = promise.then(function(){
var t = $.Deferred();
setTimeout(function() {
console.log('rejecting...');
t.reject();
}, 1000);
return t.promise();
});
promise.then(function() {
console.log('i should never be called');
})
promise.fail(function() {
console.log('i should be called');
});
deferred.resolve();
Apparently it does work the way you thought it did, it just isn't documented https://api.jquery.com/deferred.then. Very cool. This is new functionality added in jQuery 1.8.0, more than likely they just aren't done updating the documentation.