[JavaScript] 並列処理と再帰呼び出し

2018年12月3日月曜日

JavaScript

JavaScriptは基本的にイベントハンドラ内で動作しているイメージなので、シングルスレッドが前提。
そんな中で複数のループ処理を同時に動かしたいときに、うまく書けないかなーと思ってやってみた結果。

試した環境はnode.js v10.13.0

普通のループ

ものすごく簡単にいうと、こんなループを複数並列で実行したい。
function loop(i, n) {
  for (i = 0; i < 100; i++) {
    console.log(i);
  }
}

loop(0, 100);
loop(0, 100);

これを実行すると、当然
0
...
99
0
...
99
となるのだけど、これを以下のようにしたい。
0
0
1
1
...
98
98
99
99

Promiseを介した再帰

そこで、ループではなく再帰に作り変えて、Promiseに後続の処理を渡すことにする。
function parallel_for(i, n) {
  if (i >= n) return;
  console.log(i);
  Promise.resolve().then(() => parallel_for(i + 1, n));
}

parallel_for(0, 100);
parallel_for(0, 100);

これで、2つのループ処理が同時に進行するようになった。
正確には並列で動いているのではなく、代わりばんこに処理をキューに詰めているだけだけど、記法とやりたいことがマッチしているのではないだろうか。
parallel_forの引数として関数を受け取るようにすれば、汎用的にもできそう。