for文の中でawaitして返り値使う直列処理を Promise.all() で並列処理

何か日本語の不自由なタイトルだが、実際僕の思った疑問をそのまま文章にするとこんな感じだった、というか実際こういう間抜けな文章で検索していたので、このままいくことにする。

JavaScriptでfor文の中でawaitして直列でやっている処理を、Promise.all()を使って並列にやりたい、ということだ。const answers = Promise.all( …. ) と書きたい、という話。さらっと検索すると返り値を使うサンプル。

やりたいこと

論よりコードということで、以下のようなfor文があったとする。

function triangle (base, height) {
  return new Promise(resolve => {
    setTimeout(() => {
      const area = base * height / 2;
      console.log(area);
      resolve(area);
    }, 3000);
  });  
}

(async () => {
  let areas = []
  for (const i of [1, 2, 3, 4, 5]) {
    const area = await triangle(i, i);
    areas.push(area);
  }
  console.log(areas);
})();

底辺と高さが1, 2, 3, 4, 5の三角形について面積を求めて、最後に出力している。直列でやっているため、3秒ずつ結果が順番に表示され、15秒後にすべての答えが表示される。

これらの処理は独立であるので、並列で書けるはずだ。

並列化

これを並列化すると、以下のようになる。

(async () => {
  const areas = await Promise.all([1, 2, 3, 4, 5].map(async (element) => {
    return await triangle(element, element);
  }));
  console.log(areas);
})();

実行してみるとわかるが、3秒ですべての処理の答えが出るので、並列で処理してその結果を利用できることがわかる。

2つの処理を同時に走らせてみると、以下のように出力される。

0.5
0.5
2
4.5
8
12.5
[ 0.5, 2, 4.5, 8, 12.5 ]
2
4.5
8
12.5
[ 0.5, 2, 4.5, 8, 12.5 ]

まず並列処理の回答がすべて表示されて、その後逐次直列の処理の結果が出ていることがわかる。

以上。

参考

ありがとうございました。

関連記事

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。