在承诺链中容纳Q.all

我发誓Q是因为它的简单性,所以我可能没有做太多的研究来检查其他'当时'的实现。 但是我用了很多Q!

我有一个“当时”的承诺链,我想在它的中间解决一批“承诺”,按顺序进行其他的操作; 所以很明显我应该使用Q.all。 但我在这里卡住了 要么Q做错了,要么我做错了。

以下是两个假设的asynchronous操作

var f=function(delay){ return Q.delay(delay).then(function(){ console.log("returning delayed",delay) return delay }) } f2=function(delay){ var defer=Q.defer() setTimeout(function(){ console.log("returning timedout",delay) return delay },delay) return defer.promise } 

这是承诺链

  Q('begin') .then(console.log) .then(Q.all([100,200,300,400].map(f))) .then(function(){ console.log("Finally",arguments) }).done() 

这是我希望的输出

 begin returning delayed 100 returning delayed 200 returning delayed 300 returning delayed 400 Finally { '0': undefined } 

但这是我得到的输出

 begin Finally { '0': undefined } returning delayed 100 returning delayed 200 returning delayed 300 returning delayed 400 

我用f2得到相同的序列

现在,如果我运行这个

 Q.all([100,200,300,400].map(f)).then(function(){ console.log("Finally",arguments) }).done() 

我明白了

 returning delayed 100 returning delayed 200 returning delayed 300 returning delayed 400 Finally { '0': [ 100, 200, 300, 400 ] } 

但用f2而不是f给了我

 returning timedout 100 returning timedout 200 returning timedout 300 returning timedout 400 

它不执行finally块。

我用Q获得相同的输出。[all / allResolved / allSettled]

所以,我的查询是,

  1. 我如何通过使用Q.all来实现预期的输出。 我虽然有一个解决方法,但它看起来不太好。
  2. ff2不同,因为运行Q.all()。then()的结果是不一样的。

Q.all接受一组promise,但是然后返回一个promise(这是在数组中的每个promise被parsing时唯一解决的)。

所以,我想你需要返回Q.all的结果,以便不立即调用下一个:

 Q('begin') .then(console.log) .then(function() { return Q.all([100,200,300,400].map(f)); }) .then(function(){ console.log("Finally",arguments) }).done() 

回答第二个问题,你对f2的使用是不正确的。

当你使用推迟来创build一个承诺时,你必须解决它才能实现。 您可以在如何将callbackAPI转换为承诺中阅读更多信息。

在你的情况下,你正在创build一个空的延迟并返回它的承诺,但你永远不会实际调用.resolve延迟。 这样做“更正确”会是这样的:

 f2=function(delay){ var defer=Q.defer() setTimeout(function(){ console.log("returning timedout",delay) defer.resolve(delay); // note the resolve here vs the return },delay) return defer.promise } 

使用Q.delay更好,因为它已经promisified。 至于其他的实现Q现在几乎没有出血的边缘至less说:)