不幸的是,CoffeeScript 不会对涉及异步代码的这类问题提供太多帮助(除了具有更简洁的函数语法,这实际上非常好)。
您的代码有效,但有一个小警告:results
数组中值的顺序与它们在sources
. 这是一个小的工作片段,它使用setTimeout
一个随机数来获得所需的不可预测的异步行为:
calculateValues = (sources, callback) ->
counter = 0
length = sources.length
result = []
for source in sources
source.readValue (value) ->
result.push value
counter++
callback result if counter is length
sources = for i in [1..5]
do (i) ->
readValue: (cb) ->
setTimeout (-> cb "Value #{i}"), Math.random() * 1000
calculateValues sources, (results) ->
console.log "results", results
jsFiddle
样本输出:
results ["Value 2", "Value 5", "Value 1", "Value 3", "Value 4"]
如果您想保留顺序,这是一个非常简单的修复,但这展示了正确获取异步代码是多么棘手。
幸运的是,在其他工具的帮助下,有更好的方法来表达这种结构。我建议使用像Async.js这样的简单库来帮助同步事物。这是重写使用的相同片段async.parallel
和 Node 使用表单的两个参数回调的约定function(err, value)
(以及一些 Underscore.js 的小帮助,如果您不想要它可以很容易地将其转换为本机 CS):
calculateValues = (sources, callback) ->
funcs = _.pluck sources, 'readValue'
async.parallel funcs, callback
sources = for i in [1..5]
do (i) ->
readValue: (cb) ->
setTimeout (-> cb null, "Value #{i}"), Math.random() * 1000
calculateValues sources, (err, results) ->
console.log "results", results
jsFiddle
输出:
results ["Value 1", "Value 2", "Value 3", "Value 4", "Value 5"]