12

更新:这个问题是 jQuery 1.7 vs 1.8 的结果。永远不要在 1.7 中使用 Promise,因为它们不能通过在.then. 1.8 看起来他们没有搞砸。

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

预期:'我应该被调用'

实际:'我永远不应该被调用'

问题:我想要链接回调并让它们中的任何一个能够打破链接并触发fail函数,并跳过其他链接的回调。我不明白为什么所有的 then 都被触发了,而 fail 没有被触发。

我来自 NodeJS 的 Q 库,所以我.then先尝试了它。但是,将其更改为.pipe没有效果。

4

2 回答 2

12

你没有重新定义 的值promise,试试这个:

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

显然它确实按照您认为的方式工作,只是没有记录 https://api.jquery.com/deferred.then。很酷。这是 jQuery 1.8.0 中添加的新功能,很可能他们只是没有完成更新文档。

于 2012-08-27T22:03:57.030 回答
1

恕我直言,你没有链接任何东西。您的第二个.then附加到与第一个附加到相同的承诺.then

为什么?

请注意,then将始终返回新的 Promise,而不是更改它所附加的 Promise。它没有副作用。

例如:

var promiseX = promiseA
                 .then(function() { return promiseB; })
promiseX.then(function() { return promiseC; });

promiseA 附加后不会改变它的值then;它会保持原样。

promiseX将是 1st 的返回值then,即promiseB.

所以第二个then实际上是附加到promiseB.

这正是@Kevin B 在他的回答中所做的。


另一个解决方案是,由于.then将返回新的承诺,您可以.then像下面这样链接函数。

var promiseX = promiseA
                 .then(function() { return promiseB; })
                 .then(function() { return promiseC; });

这一次,第一个then被附加到promiseA,猜猜第二个then被附加到哪个承诺?

你是对的。是promiseB,不是promiseA。因为 2ndthen实际上是附加到 1st 的返回值then,即promiseB.

最后将 2ndthen的返回值赋值给promiseX,所以promiseX等于promiseC

好的,回到OP的问题。以下代码是我的答案。

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();
于 2015-09-07T07:28:49.347 回答