更新:此问题是jQuery 1.7 vs 1.8的结果。不要在1.7中使用promises,因为它们在.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
无效。
答案 0 :(得分:11)
您没有重新定义promise
的值,请尝试以下操作:
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中添加的新功能,很可能他们只是没有更新文档。
答案 1 :(得分: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; });
这次,第一个then
附加到promiseA
,并猜测哪个承诺是附加的第二个then
?
promiseB
,而不是promiseA
。因为第二个then
实际上附加到第一个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();