2012-04-24 189 views
14

处理多个异步回调的最佳方式/库是什么?现在,我有这样的事情:Javascript - 等待一些异步回调返回?

_.each(stuff, function(thing){ 
    async(thing, callback); 
}); 

我需要回调已stuff被解雇的每个元素后执行一些代码。

干净的方法是什么?我愿意使用库。

+0

的可能重复[多个异步等待呼叫之前继续完成(http://stackoverflow.com/questions/2768293/waiting-on-multiple-asynchronous-calls-to-complete-before-continuing ) – RMalke 2014-04-26 15:32:22

回答

12

有一个伟大的图书馆叫Async.js,帮助解决这样的问题,许多异步&流量控制助手。它提供了几个forEach函数,可以帮助您为数组/对象中的每个项目运行回调。

退房: https://github.com/caolan/async#forEach

// will print 1,2,3,4,5,6,7,all done 

var arr = [1,2,3,4,5,6,7]; 

function doSomething(item, done) { 
    setTimeout(function() { 
    console.log(item); 
    done(); // call this when you're done with whatever you're doing 
    }, 50); 
} 

async.forEach(arr, doSomething, function(err) { 
    console.log("all done"); 
}); 
+0

这很好,如果这可以处理我的链接,我可能会在稍后进行切换。这是否比只使用_.after之类的计数器更智能? – 2012-04-24 03:14:59

+0

很酷的事情是你可以做'async.forEachSerial',如果你想让它们一个接一个地运行。它给你灵活性。对于一个简单的用例,是的,计数的东西很好用,并且内置在下划线中。做吧! – 2012-04-24 03:19:18

+0

我最终需要使用'系列',并且切换到异步清理了*相当*。我也很确定我在这个过程中发现了一个回调时间问题。 – 2012-04-25 20:05:07

0

有一个计数器,说async_count。每当你开始一个请求时(在你的循环中)增加一个,并且让回调减少一个,并检查是否已经达到零 - 如果是的话,所有的回调已经返回。

编辑:虽然,如果我是写这个的人,我会链接请求,而不是并行地运行它们 - 换句话说,我有一个队列的请求,并有回调检查队列中的下一个请求使。

28

既然你已经使用下划线你可能看_.after。它完全符合你的要求。从文档:

      _.after(count, function)

创建一个版本后,才第一次被称为计数的时间点运行的功能。在继续之前,用于对异步响应进行分组,这对于确保所有异步调用已完成的情况非常有用。

+1

这很好用。 – 2012-04-24 03:14:25

2

为此,我建议使用https://github.com/caolan/async。您可以使用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 
} 
+0

为什么不'async.forEach'? – 2012-04-24 03:06:58

+0

我认为在这种情况下,async.forEach和async.parallel基本相同。 forEach的文档甚至会说“它并行执行”。 “平行”的名字使这个更清晰。 – 2012-04-24 12:50:04

+0

嗯,是的,看起来forEach在这种情况下更合适,因为它会处理你的闭包,你可以给它一个常规函数和一个数据列表。 – 2012-04-24 19:13:27

1

async.parallel()/ async.series应该符合您的要求。当所有REST调用成功时,您可以提供最终回调。

async.parallel([ 
    function(){ ... }, 
    function(){ ... } 
], callback); 
async.series([ 
    function(){ ... }, 
    function(){ ... } 
], callback);