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 looks like they didn't mess it up.
http://jsfiddle.net/delvarworld/28TDM/
// make a promise
var deferred = $.Deferred();
promise = deferred.promise();
// return a promise, that after 1 second, is rejected
promise.then(function(){
var t = $.Deferred();
setTimeout(function() {
console.log('rejecting...');
t.reject();
}, 1000);
return t.promise();
});
// if that promise is successful, do this
promise.then(function() {
console.log('i should never be called');
})
// if it errors, do this
promise.fail(function() {
console.log('i should be called');
});
deferred.resolve();
Expected: 'i should be called'
Actual: 'i should never be called'
Problem: I want to chain callbacks and have any one of them be able to break the chain and trigger the fail
function, and skip the other chained callbacks. I don't understand why all of the thens are triggered and the fail is not triggered.
I'm coming from NodeJS's Q library, so I tried it with .then
first. However, changing it to .pipe
has no effect.
You aren't re-defining the value of
promise
, try this:http://jsfiddle.net/28TDM/1/
Apparently it does work the way you thought it did,
it just isn't documentedhttps://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.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:
promiseA
won't change its value after being attachedthen
; it'll keep as is.promiseX
will be the return value of the 1stthen
, that is,promiseB
.So the 2nd
then
is actually attached topromiseB
.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.This time, the 1st
then
is attached topromiseA
, and guess to which promise is the 2ndthen
being attached to?You're right. It's
promiseB
, notpromiseA
. Because the 2ndthen
is actually being attached to the return value of the 1stthen
, i.e.,promiseB
.And finally the 2nd
then
's return value is assigned topromiseX
, sopromiseX
equalspromiseC
.Ok, get back to the OP's question. The following code is my answer.