我有一个函数,它在for循环中包含另一个函数调用。
outerFunction(){
for (var j = 0; j < geoAddress.length; j++) {
innerFunction(j);
}
}
我需要等到对innerFunction的所有调用都完成。如果我需要并行执行这些函数,如何在JavaScript中实现这一点?
答案 0 :(得分:2)
查看异步库。 https://www.npmjs.org/package/async
查看#34;&#34;的文档。听起来它只是你所需要的。 而(测试,fn,回调)
var count = 0;
async.whilst(
function () { return count < 5; },
function (callback) {
count++;
setTimeout(callback, 1000);
},
function (err) {
// 5 seconds have passed
}
);
答案 1 :(得分:2)
编辑 - 使用Q承诺库以节点方式做事
如果您正在使用Q promise库,请尝试以下操作:
outerFunction(){
var promises = [];
for (var j = 0; j < geoAddress.length; j++) {
deferreds.push(innerFunction(j));
}
Q.all(promises).then(function(){
// do things after your inner functions run
});
}
即使您不使用此特定库,原理也是一样的。一个人应该有一个函数返回一个promise或者将它包装在一个promise中,就像在Q.denodify方法中一样,将所有调用推送到一个promises数组,将所述数组传递给你的库等同于.when ()(jQuery)或.all()(Q Promise Library)然后使用.then()在所有promises解决后执行操作。
答案 2 :(得分:0)
outerFunction() {
var done = 0;
function oneThreadDone() {
done++;
if (done === geoAddress.length) {
// do something when all done
}
}
for (var j = 0; j < geoAddress.length; j++) {
setTimeout(function() { innerFunction(j, oneThreadDone); }, 0);
}
}
和内部函数内部调用oneThreadDone()函数(通过param传递的引用)
答案 3 :(得分:0)
如果你不想为此使用外部库,你可以创建一个范围对象,例如process
,跟踪有多少innerFunction
个呼叫仍在等待,并调用外部回调完成后cb
。
关键在于您仍然可以获得异步执行的好处,但是您只需确保您的代码不会执行下一部分,直到属于outerFunction的所有innerFunction实际完成为止:
outerFunction(function() {
console.log("All done for outerFunction! - What you should do next?");
// This block is executed when all innerFunction calls are finished.
});
<强> JavaScript的:强>
// Example addresses
var geoAddress = ["Some address X", "Some address Y"];
var innerFunction = function(geoAddress, process) {
// Your work to be done is here...
// Now we use only setTimeout to demonstrate async method
setTimeout(function() {
console.log("innerFunction processing address: " + geoAddress);
// Ok, we update the process
process.done();
}, 500);
};
var outerFunction = function(cb) {
// Process object for tracking state of innerFunction executions
var process = {
// Total number of work ahead (number of innerFunction calls required).
count: geoAddress.length,
// Method which is triggered when some call of innerFunction finishes
done: function() {
// Decrease work pool
this.count--;
// Check if we are done & trigger a callback
if(this.count === 0) {
setTimeout(cb, 0);
}
}
};
for (var j = 0; j < geoAddress.length; j++) {
innerFunction(geoAddress[j], process);
}
};
// Testing our program
outerFunction(function() {
console.log("All done for outerFunction! - What you should do next?");
// This block is executed when all innerFunction calls are finished.
});
<强>输出:强>
innerFunction processing address: Some address X
innerFunction processing address: Some address Y
All done for outerFunction! - What you should do next?
干杯。