试图用.then,.fail和.reject打破jQuery承诺链

更新:此问题是jQuery 1.7 vs 1.8的结果。 不要在1.7中使用promises,因为它们不能在.then内返回一个promise。 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中添加的新function,很可能他们没有完成更新文档。

恕我直言,你没有任何链接。 你的第二个。然后是第一个.then附加的承诺

为什么?

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

例如:

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

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

promiseX将是第一个的返回值,即promiseB

所以第二个实际上附属于promiseB

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


另一个解决方案是,因为.then将返回新的承诺,你可以链接.then函数,如下所示。

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

这一次,第一个是附属于promiseA ,并猜测哪个承诺是第二个then附加到?

你是对的。 这是promiseB ,而不是promiseA 因为第二个then实际上被附加到第一个的返回值,即promiseB

最后将第二个返回值分配给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();