等到for循环中的所有函数调用结束其执行 - Javascript

时间:2014-07-22 14:34:31

标签: javascript node.js loops asynchronous

我有一个函数,它在for循环中包含另一个函数调用。

outerFunction(){ 
    for (var j = 0; j < geoAddress.length; j++) {
         innerFunction(j);
    }
}

我需要等到对innerFunction的所有调用都完成。如果我需要并行执行这些函数,如何在JavaScript中实现这一点?

4 个答案:

答案 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? 

这是 js fiddle example

干杯。