蓝鸟嵌套承诺与每个/传播
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(',')
[...]
说明
我想用1
、2
、3
(依次)运行相同的函数,所以我使用了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()。
【讨论】:
以上是关于蓝鸟嵌套承诺与每个/传播的主要内容,如果未能解决你的问题,请参考以下文章