31

forEach次のような二重ループ内でいくつかの計算を行っています。

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

        /* some complex computations with asynchronous callbacks  */        

    });
});

someFunctionHere();

someFunctionHere( )関数を実行する前にループを最初に終了する方法はありますか? または、続行する前にループが終了したかどうかをプログラムが知る方法someFunctionHere( )...

いくつかのフォーラムが不足している可能性がありますが、見つけたフォーラムは私が達成したいことを助けてくれませんでした.NodeJSでこれを行っているので、これを実現できる既存のライブラリがあるかどうかも尋ねています.

これを追加するのを忘れましたか、それとも別の質問にする必要がありますか?

現在の反復が完了すると、次の反復にのみ進むように反復を同期的に行う方法はありますか? (ごめんなさい)

助けてくれてありがとう...

4

5 に答える 5

45

async.js、特に や などの制御フローステートメントを見てください。each whilstuntil

async.js を使用すると、必要なものを取得できます。

実際の状況では、必要なのはeach関数 (以前は として知られていましたforEach) であり、それぞれ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 :-)!');
});

これは、素数の配列を繰り返し処理し、それらを正しい順序で順番に出力し、最後に を出力しWell done :-)!ます。

于 2013-03-01T16:17:06.487 に答える
7

カウントダウン クロージャでコールバックをラップできます。

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  */

    });
});

argumentsコールバックの引数の数が異なる場合は、明示的なパラメーターを使用する代わりに、少し手術を行うことができcallbackArgsます。

EDIT編集は、前の計算がコールバックを完了した後に各複雑な計算を開始することを明確にします。これは、クロージャーを介して簡単に配置することもできます。

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);
于 2013-03-01T16:22:32.827 に答える