Async: ネストされた非同期呼び出しを持つeachSeriesは、最大呼び出しスタックサイズを超えます

作成日 2016年08月10日  ·  3コメント  ·  ソース: caolan/async

どのバージョンの非同期を使用していますか?

2.0.1

どの環境で問題が発生しましたか(ノードバージョン/ブラウザバージョン)

ノード6.2.1
NPM 3.9.3

あなたは何をした?

let counter = 2000;

async.eachSeries(
  new Array(counter),
  (item, cb) => {
    async.parallel([
      (pCb) => {
        console.log(counter--);
        pCb();
      },
    ], cb);
  },
  () => console.log('done')
);

何が起こると思いましたか?

それぞれの反復が発生することを期待していました。その結果、最後の2つのconsole.logが「1」と「done」になります。

実際の結果はどうでしたか?

1000回未満の反復の後、次のエラーが発生します。

RangeError:最大コールスタックサイズを超えました

非同期1.5.2に戻すと、上記のコードは期待どおりに機能しました。

question

最も参考になるコメント

これが非同期1.5.2で機能した理由は、そのバージョンではコールバックが常に非同期で呼び出されるようにしたためです。 バージョン2では、このガードを削除しました(https://github.com/caolan/async/blob/master/intro.md#synchronous-iteration-functionsを参照)

したがって、スクリプトを修正する場合は、 async.ensureAsync(cb)またはasync.setImmediate(cb)を使用して、再帰の問題を回避できます。

var counter = 2000;

async.eachSeries(
  new Array(counter),
  (item, cb) => {
    async.parallel([
      (pCb) => {
        console.log(counter--);
        async.setImmediate(pCb);
      },
    ], cb);
  },
  () => console.log('done')
);

全てのコメント3件

+1

+1

これが非同期1.5.2で機能した理由は、そのバージョンではコールバックが常に非同期で呼び出されるようにしたためです。 バージョン2では、このガードを削除しました(https://github.com/caolan/async/blob/master/intro.md#synchronous-iteration-functionsを参照)

したがって、スクリプトを修正する場合は、 async.ensureAsync(cb)またはasync.setImmediate(cb)を使用して、再帰の問題を回避できます。

var counter = 2000;

async.eachSeries(
  new Array(counter),
  (item, cb) => {
    async.parallel([
      (pCb) => {
        console.log(counter--);
        async.setImmediate(pCb);
      },
    ], cb);
  },
  () => console.log('done')
);
このページは役に立ちましたか?
0 / 5 - 0 評価