蓝鸟嵌套承诺与每个/传播

Posted

技术标签:

【中文标题】蓝鸟嵌套承诺与每个/传播【英文标题】:Bluebird nested promises with each/spread 【发布时间】:2015-07-08 23:11:06 【问题描述】:

我在使用 bluebird Promises 时遇到了问题。我正在使用 CoffeeScript,但也欢迎 javascript 答案:)

这是我想要做的:

代码示例

Promise = require 'bluebird'
Model = Promise.promisifyAll(require '[...]') # mongoose model promisified

getOpts = () -> [...] # whatever

Promise.each [1..3], (number) ->
  opts = getOpts(number)
  return Model.count(opts).exec (err, count) ->
    return "the count is #count"
.spread () ->
  console.log JSON.stringify arguments
  result = arguments.join(',')
  [...]

说明

我想用123(依次)运行相同的函数,所以我使用了bluebird的.each函数。 在函数中,我需要从我的数据库中获取计数。我正在使用 mongoose 和 bluebird 的 promisifyAll 函数来返回一个 Promise 并确保 .each 等到每个查询完成后再进行下一步。

然后,我想收集每个查询的结果。我正在使用蓝鸟的spread 来收集.each 的返回值。但是,它不包含嵌套承诺的返回值。 arguments 值为:


  "0": 1,
  "1": 2,
  "2": 3

有什么想法吗?

谢谢

编辑

看起来蓝鸟的.each.spread 不匹配。我正在调查这个问题。

编辑 2

(感谢伯吉)

我找到了一个解决方案:首先我构建了一个函数数组。然后我在这个数组上调用bluebird的.all,然后调用.spread

编辑 3

好的,我终于尝试了.map 而不是.each,它也很好用。

【问题讨论】:

【参考方案1】:

看起来 bluebird 的 .each.spread 不匹配

确实如此。 each 确实返回了一个数组的承诺,如果你想使用那个 array 只需使用 then:

Promise.each [1..3], (number) ->
  opts = getOpts(number)
  Model.countAsync(opts).then (count) ->
    "the count is #count"
.then (args) ->
  console.log JSON.stringify args
  result = args.join(',')
  […]

spread 仅适用于希望为每个数组元素使用单个变量(函数参数)的回调函数,例如 .spread (firstResult, secondResult, thirdResult) -> …

另外,arguments 是一个类似数组的对象,而不是真正的数组,这就是为什么你会得到奇怪的 JSON 表示以及为什么 .join 调用确实会引发异常。

但是,它不包含嵌套promise的返回值

是的,each 最初只被认为是副作用,而不是收集结果,它返回原始输入。这将随着版本 3.0 改变。在此之前,您可以使用map。详情请见Bluebird: getting the results of each()。

【讨论】:

以上是关于蓝鸟嵌套承诺与每个/传播的主要内容,如果未能解决你的问题,请参考以下文章

处理嵌套承诺的最佳方法(蓝鸟)[重复]

与蓝鸟的承诺链阵列

猫鼬承诺与蓝鸟和打字稿

蓝鸟承诺未定义?

如何在 Model.find( obj , callback) 上传播回调承诺值?

蓝鸟,承诺,然后()