我如何同时调用asynchronous函数并等待所有callback?

在nodeJS中,我如何同时调用asynchronous函数并等待所有的callback才能继续?

在下面的示例中,我只希望主返回all_results只有当f1f2f3完成callback()

 function main(callback){ var all_results = []; f1(function(results){ all_results.push(result) }); f2(function(results){ all_results.push(result) }); f3(function(results){ all_results.push(result) }); // when all 3 calls are complete: callback(all_results) } function f1(callback){ ... callback(results); } function f2(callback){ ... callback(results); } function f3(callback){ ... callback(results); } 

不使用承诺。

您不能以同步方式返回asynchronous检索的结果。 所以函数main不能返回结果。 你应该坚持你select的asynchronous方法。 所以在callback的时候,你也应该在调用main时提供一个callback函数:

 function main(callback){ var all_results = []; function collect(results) { all_results.push(results); // when all 3 calls are complete: if (all_results.length === 3) callback(all_results); } f1(collect); f2(collect); f3(collect); } 

这样的电话:

 main(function (all_results) { console.log(all_results); }); 

正如其他人所说,承诺会在这种情况下导致更好的代码。

如何与承诺做到这一点

假设您不能修改函数f1f2f3 ,那么您可以使用一个简单的帮助函数创build它们的promisified版本。 一旦完成,包含ES6的方法Promise.all将完成剩下的工作,所以代码变得相当简洁。

下面是一个片段,它定义了一些使用setTimeout获取asynchronous效果的虚拟函数f1f2f3

 function promisify(f) { return new Promise(f); } function main(){ return Promise.all([f1, f2, f3].map(promisify)); } main().then(function (results) { console.log(results); }); function f1(callback){ setTimeout(function () { callback('result from f1'); }, 100); } function f2(callback){ setTimeout(function () { callback('result from f2'); }, 500); } function f3(callback){ setTimeout(function () { callback('result from f3'); }, 200); } 

为每个函数添加一个布尔variables,只有当所有的都设置时才返回:

 function main(callback){ var all_results = []; var finished = [false, false, false]; f1(function(results){ all_results.push(result) finished[0] = true; }); f2(function(results){ all_results.push(result) finished[1] = true; }); f3(function(results){ all_results.push(result) finished[2] = true; }); var t = setInterval(checkFinished,1000); function checkFinished(){ if(finished[0] && finished[1] && finished[2]){ clearInterval(t) callback(all_results) } } }