gpt4 book ai didi

coffeescript - 是否可以通过 CoffeeScript 理解从回调中收集结果?

转载 作者:行者123 更新时间:2023-12-02 14:36:30 25 4
gpt4 key购买 nike

假设我有对象数组,每个对象都有一些异步 readValue 函数,该函数接受回调作为其参数,当该对象的值可用时将触发该函数。

我的目标是计算每个对象的所有值并返回包含这些值的数组。

我首先想到的是这个

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 方法是异步的,因此调用它的函数也是异步的。当所有值都在 result 数组中时,callback 函数将被执行。

但这一切对我来说似乎很困惑。这是coffescript真正强大的领域。即使用更少的代码和推导式也可以编写这个函数吗?如果是同步的就可以了。

最佳答案

不幸的是,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"]

关于coffeescript - 是否可以通过 CoffeeScript 理解从回调中收集结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16068797/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com