Node.js 阻止,直到承诺得到解决
给定以下Coffeescript代码:Node.js 阻止,直到承诺得到解决,node.js,coffeescript,q,Node.js,Coffeescript,Q,给定以下Coffeescript代码: for groupID, groupObj of @cache.groups #do some other stuff #calling this function which is returning a promise @callcounter.findNumbers(groupID) .then (result) => @cache.groups[groupID].someValue = result.someVal
for groupID, groupObj of @cache.groups
#do some other stuff
#calling this function which is returning a promise
@callcounter.findNumbers(groupID)
.then (result) =>
@cache.groups[groupID].someValue = result.someValue
在幕后,方法findNumbers
正在查询SQL数据库(使用冗长的,不支持并发查询)并返回承诺(库:Q)
因此,在前一个循环的承诺得到解决之前,代码执行不应转到for
-循环的下一个迭代
您将如何以正确的方式执行此操作?您所需要的只是对
findNumbers
的调用是按顺序进行的,对吗?你只需要把你的承诺串起来
重要提示:因为您使用的是命令式循环而不是[].forEach,所以需要确定groupID
和groupObject
变量的范围
globalPromise = null
createScopedPromiseFn = (groupID, groupObject) =>
return ->
@callcounter.findNumbers(groupID).then (result) =>
@cache.groups[groupID].someValue = result.someValue
for groupID, groupObj of @cache.groups
createPromise = createScopedPromiseFn groupID, groupObj
# The if here is for initialisation
globalPromise = if globalPromise then globalPromise.then createPromise() else createPromise()
globalPromise.then ->
# Here you have finished
在这段代码中,for
循环无限制地迭代,但承诺实际上是按顺序解析的
但是,我建议您采用功能性方法,使用reduce
:
createScopedPromise = (groupIndex, group) =>
@callcounter.findNumbers(groupIndex).then (result) =>
@cache.groups[groupIndex].someValue = result.someValue
globalPromise = @cache.groups.reduce (promise, group, index) ->
if promise
return promise.then ->
createScopedPromise index, group
else # First promise
return createScopedPromise index, group
globalPromise.then ->
# Here you have finished
请允许我问一下,为什么这个问题被否决了?谢谢。功能性方法看起来很有希望。不过有一个缺点。似乎我不应该在同一个
reduce
中做其他事情。事实上,我这么做是因为这很容易做到。但是在我看来,在你的函数方法中做同样的事情是错误的。没关系。