Search code examples
jquerydeferredchainpromise

attempting to break jQuery promise chain with .then, .fail and .reject


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.


Solution

  • 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.