Javascript-等待大量异步回调返回?
处理多个异步回调的最佳方法/库是什么?现在,我有这样的想法:Javascript-等待大量异步回调返回?,javascript,asynchronous,underscore.js,Javascript,Asynchronous,Underscore.js,处理多个异步回调的最佳方法/库是什么?现在,我有这样的想法: _.each(stuff, function(thing){ async(thing, callback); }); 我需要在为stuff中的每个元素启动回调后执行一些代码 最干净的方法是什么?我愿意使用库。有一个计数器,比如说async\u count。每次启动请求时(在循环内部)将其增加1,让回调将其减少1,并检查是否已达到零-如果是,则所有回调都已返回 编辑:尽管如此,如果是我写这篇文章的话,我会将请求链接起来,而不是并
_.each(stuff, function(thing){
async(thing, callback);
});
我需要在为stuff
中的每个元素启动回调后执行一些代码
最干净的方法是什么?我愿意使用库。有一个计数器,比如说
async\u count
。每次启动请求时(在循环内部)将其增加1,让回调将其减少1,并检查是否已达到零-如果是,则所有回调都已返回
编辑:尽管如此,如果是我写这篇文章的话,我会将请求链接起来,而不是并行运行它们——换句话说,我有一个请求队列,让回调函数检查队列,以便下一个请求发出。有一个很棒的库,名为,它可以帮助解决许多异步和流控制助手遇到的类似问题。它提供了几个forEach函数,可以帮助您为数组/对象中的每个项运行回调 退房:
因为您已经在使用下划线,所以可以查看。它完全符合你的要求。从文档中: 之后
之后
创建函数的一个版本,该版本仅在第一次被调用计数后运行。用于对异步响应进行分组,您希望在继续之前确保所有异步调用都已完成
见我对类似问题的回答: My
fork()
函数在内部自动维护计数器。我建议这样做。您可以使用async.parallel
来执行此操作
function stuffDoer(thing) {
return function (callback) {
//Do stuff here with thing
callback(null, thing);
}
}
var work = _.map(stuff, stuffDoer)
async.parallel(work, function (error, results) {
//error will be defined if anything passed an error to the callback
//results will be an unordered array of whatever return value if any
//the worker functions passed to the callback
}
async.parallel()/async.series应该适合您的要求。您可以提供一个最终回调,在所有REST调用成功时执行该回调
async.parallel([
function(){ ... },
function(){ ... }
], callback);
async.series([
function(){ ... },
function(){ ... }
], callback);
这是好的,如果这可以处理链接为我,我可能会使这个开关以后。这比简单地使用像u.after这样的计数器更智能吗?很酷的一点是,如果你想让它们一个接一个地运行,你可以做
async.forEachSerial
。它给你灵活性。对于一个简单的用例,是的,计数功能非常有效,并且内置在下划线中。做吧!最后,我需要大量使用“series”,而切换到async则让事情变得更加简单。我也很确定我在这个过程中发现了回调时间问题。@StefanKendall很有趣!如果我记得,如果您立即返回,可能会出现问题,这意味着您的函数不是异步的。我相信这可以通过在setTimeout(fn,0)中包装早期返回来解决!我认为在这种情况下,async.forEach和async.parallel基本上是相同的。forEach上的文档甚至说“它并行执行它们”。“parallel”的名字让这一点更清楚。嗯,是的,在这种情况下forEach似乎更合适,因为它将为您处理闭包,您可以给它一个常规函数和一个数据列表。可能是
async.parallel([
function(){ ... },
function(){ ... }
], callback);
async.series([
function(){ ... },
function(){ ... }
], callback);