2012-04-24 59 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);