是否可以通过coffeescript理解从回调中收集结果?
假设我有一个对象数组,每个对象都有一些异步的是否可以通过coffeescript理解从回调中收集结果?,coffeescript,list-comprehension,for-comprehension,Coffeescript,List Comprehension,For Comprehension,假设我有一个对象数组,每个对象都有一些异步的readValue函数,它接受callback作为它的参数,当这个对象的值可用时,它将被激发 我的目标是计算每个对象的所有值,并用这些值返回数组 我首先想到的是这个 calculateValues = (sources, callback) -> counter = 0 length = sources.length result = [] for source in sources source
readValue
函数,它接受callback作为它的参数,当这个对象的值可用时,它将被激发
我的目标是计算每个对象的所有值,并用这些值返回数组
我首先想到的是这个
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
由于readValue
方法是异步的,所以调用它的函数也是异步的。当所有值都在结果
数组中时,将执行回调
函数
但我觉得这一切都很混乱。这就是coffeescript真正强大的领域。即使代码不那么复杂,也能编写这个函数吗?如果它是同步的,那没关系。不幸的是,CoffeeScript在处理这些涉及异步代码的问题时帮不了你多少忙(除了有一个更简洁的函数语法,实际上这很好) 您的代码可以工作,但有一点需要注意:
结果
数组中的值顺序与源
中的源顺序不匹配。下面是一个小的工作片段,它使用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
样本输出:
结果[“值2”、“值5”、“值1”、“值3”、“值4”]
如果您想保留顺序,这是一个非常简单的修复程序,但这说明了正确获取异步代码是多么棘手
幸运的是,在其他工具的帮助下,有更好的方法来表达这种构造。我建议使用一个简单的库来帮助同步。下面是重写的相同代码段和Node的约定,即使用函数(err,value)
的两个参数回调(还有一点下划线.js小帮助,如果不需要,可以很容易地将其转换为本机CS):
输出:
结果[“值1”、“值2”、“值3”、“值4”、“值5”]
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