(JavaScript)使用里面的回调同步forEach循环

meg*_*oth 29 javascript node.js

我在双forEach循环内做一些计算,如下所示:

array.forEach(function(element){
    Object.keys(element).forEach(function(key){

        /* some complex computations with asynchronous callbacks  */        

    });
});

someFunctionHere();
Run Code Online (Sandbox Code Playgroud)

在执行该someFunctionHere( )功能之前,Loop是否有办法先完成?或者任何方式,程序将知道循环是否完成后继续someFunctionHere( )...

我可能会错过一些论坛,但我找到的那些论坛并没有帮助我实现我想要实现的目标,而且我在NodeJS中这样做,我也在问是否有现有的库可以实现这一点.

我忘了添加它或者这是另一个问题吗?

有没有办法同步进行迭代,它只会在当前迭代完成后进入下一次迭代?(非常遗憾)

谢谢你的帮助...

Gol*_*den 44

看一下async.js,特别是它的控制流语句,比如each whilst和until.

使用async.js可以获得您想要的内容.

在您的实际情况中,您想要的是each函数(以前称为forEach),分别是eachSeries不并行运行单个迭代的函数,而是串行运行的函数(有关详细信息,请参阅eachSeries的文档).

举个例子:

async.eachSeries([ 2, 3, 5, 7, 11 ], function (prime, callback) {
  console.log(prime);
  callback(); // Alternatively: callback(new Error());
}, function (err) {
  if (err) { throw err; }
  console.log('Well done :-)!');
});
Run Code Online (Sandbox Code Playgroud)

这将遍历素数数组并以正确的顺序打印它们,一个接一个地打印出来,最后打印出来Well done :-)!.


Ted*_*opp 6

您可以在倒计时闭包中包装回调:

var len = array.length;

function countdownWrapper(callback, callbackArgs) {
    callback(callbackArgs);
    if (--len == 0) {
        someFunctionHere();
    }
}

array.forEach(function(element){
    Object.keys(element).forEach(function(key){

        var wrappedCallback = countdownWrapper.bind(callback);
        /* some complex computations with asynchronous WRAPPED callbacks  */

    });
});
Run Code Online (Sandbox Code Playgroud)

如果回调具有不同数量的参数,则可以进行一些手术,arguments而不是使用显式callbackArgs参数.

编辑您的编辑说明您希望在上一次计算完成回调后启动每个复杂计算.这也可以通过闭包轻松安排:

function complexOp(key, callback) { /* . . . */ }

function originalCallback(...) { /* . . . */ }

function doSomethingElse() { /* . . . */ }

var iteratorCallback = (function (body, callback, completion) {
    var i = 0, len = array.length;
    return function iterator() {
        callback.apply(null, arguments);
        if (++i < len) {
            body(array[i], iterator);
        } else {
            completion();
        }
    };
}(complexOp, originalCallback, doSomethingElse)); 

// kick everything off:
complexOp(array[0], iteratorCallback);
Run Code Online (Sandbox Code Playgroud)