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

后端 未结 2 579
南旧
南旧 2021-02-05 20:20

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

2条回答
  •  攒了一身酷
    2021-02-05 21:19

    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();
    

提交回复
热议问题