Bluebird 嵌套承诺 each/spread

Bluebird nested promises with each/spread

我在使用 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 函数来 return Promise 并确保 .each 等到每个查询完成后再进行下一步。

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

{
  "0": 1,
  "1": 2,
  "2": 3
}

有什么想法吗?

谢谢

编辑

看起来 bluebird 的 .each.spread 不太相配。我正在调查这个问题。

编辑 2

(感谢 Bergi)

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

编辑 3

好的,我终于尝试了 .map 而不是 .each,而且效果也很好。

Looks like bluebird's .each doesn't go well with .spread

确实如此。 each 对数组做 return 承诺,如果你想使用那个 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 调用会抛出异常。

However, it doesn't contain the return value of the nested promise

是的,each 最初只是考虑副作用,而不是收集结果,它 return 是原始输入。这将随着 3.0 版而改变。在那之前,您可以使用 map。有关详细信息,请参阅