3

実行のブロックを解除するために、配列を非同期的に反復処理したいと考えています。私はそれを達成するために caolan/async を使用しています。このコードをテストする場合:

var ASync = require('async');

var arr = [];
for (var i = 0; i< 10; i++) {
    arr[i] = i;
}

var buf = "howdy";
ASync.forEach(arr, function(item, callback) {
    buf += item;
    callback();
}, function(err) {
    console.log(buf); // in the end
});
buf += "finished";

次の結果が表示されます。

howdy0123456789

私はそれが表示されるはずだと思います

howdyfinished0123456789

非同期ライブラリが実行を延期することを期待しているためです。しかし、なぜそうではないのですか?

4

2 に答える 2

4

コードでcallbackは、それ自体と同じイベント ループの反復で実行されforeachます。現在のイベント ループの反復から外れることがないため、buf += "finished"すべてbuf += itemが実行された後にのみ実行されます。

適切なバージョンは

var ASync = require('async');

var arr = [];
for (var i = 0; i< 10; i++) {
    arr[i] = i;
}

var buf = "howdy";
ASync.forEach(arr, function(item, callback) {
    process.nextTick(function () {
        buf += item;
        callback();
    });
}, function(err) {
    console.log(buf); // in the end
});
buf += "finished";

最終的に、bufは に等しくなりhowdy0finished123456789ます。

ただし、このタスクは単純化されすぎています。なぜ非同期ループが必要なのですか?

  1. 非同期タスクを並行して実行するため。まず、各タスクは非同期であるcallbackため、同じイベント ループの反復をトリガーするのではなく、特定の非同期タスクに与えます。第二に、async.parallelこの種のタスクにより適しています。

  2. 一部の CPU 集中型タスクを実行するため、イベント ループのフリーズを回避します (ノードが反復の間にいくつかのタスクを処理できるようにするため)。これは、上記のコード例で想定していることです。Array.prototype.forEachループのすべての反復が処理されたイベントの検出を何らかの方法で実装する必要があるため、プレーンな JS (およびその組み込み) を使用してこのタスクを達成するのは非常に困難です。

于 2012-08-21T10:10:56.213 に答える
1

これを読むべきだと思います: http://howtonode.org/understanding-process-next-tick

于 2012-08-21T10:18:27.140 に答える