更新:此问题是jQuery 1.7 vs 1.8的结果。不要在1.7中使用承诺,因为它们不能在一个承诺中回复 .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
函数,并跳过其他链式回调。我不明白为什么所有的游戏都被触发,并且没有触发失败。
我来自NodeJS的Q库,所以我尝试了 .then
第一。但是,将其更改为 .pipe
没有效果。
你没有重新定义它的价值 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中添加的新功能,很可能他们没有完成更新文档。
恕我直言,你没有任何链接。 你的第二个 .then
与第一个承诺相同 .then
附在。
为什么?
请注意, then
会一直 返回 新承诺,而不是改变它所附带的承诺。它没有副作用。
例如:
var promiseX = promiseA
.then(function() { return promiseB; })
promiseX.then(function() { return promiseC; });
promiseA
不会改变它的价值 被附上后 then
;它会保持原样。
promiseX
将是第一个的返回值 then
, 那是, promiseB
。
所以第二个 then
实际上是附属于 promiseB
。
这正是@Kevin B在他的回答中所做的。
另一种解决方案是,因为 .then
将返回新的承诺,你可以链接 .then
功能如下。
var promiseX = promiseA
.then(function() { return promiseB; })
.then(function() { return promiseC; });
这一次,第1次 then
附在 promiseA
,并猜测哪个承诺是第二个 then
被附着?
你是对的。它的 promiseB
不是 promiseA
。因为第二个 then
实际上是附加到第1个的返回值 then
,即 promiseB
。
最后是第二名 then
的返回值被分配给 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();