在承诺链中容纳Q.all



我对Q的简单性深信不疑,所以我可能没有做太多研究来检查其他"then"实现。但我用了Q很多!

我有一个"然后"的承诺链,我想解决中间的"一批"承诺,并按顺序进行其他操作;所以很明显我应该使用Q.all。但我被困在这里了。要么Q做错了,要么我做错了。

以下是两个假设的异步操作

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 ] }

但是用CCD_ 2代替CCD_

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

它不执行finally块。

我用Q.[allResolved/allSettled]得到相同的输出

所以,我的问题是,

  1. 我如何通过专门使用Q.all来实现预期的输出。我确实有一个变通办法,但看起来不太好
  2. ff2有什么不同,因为用它们运行Q.all((.then((的结果不一样

Q.all接受一个promise数组,但返回一个prome(当数组中的每个promise都被解析时,这是唯一被解析的(。

因此,我认为您需要返回Q.all的结果,以便不立即调用下一个then:

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

在回答第二个问题时,您对f2的使用是错误的。

当你使用延期创建承诺时,你必须解决它才能实现。您可以在如何将回调API转换为promise中了解更多信息。

在您的案例中,您创建了一个空的deferred并返回其promise,但实际上从未在deferred上调用.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效果更好,因为它已经被承诺了。至于其他then实现,至少可以说Q现在几乎没有流血:(

相关内容

  • 没有找到相关文章

最新更新