web-dev-qa-db-ja.com

VS Promise.allを待つために

これには違いがありますか?

const promises = await Promise.all(items.map(e => somethingAsync(e)));
for (const res of promises) {
  // do some calculations
}

この ?

for await (const res of items.map(e => somethingAsync(e))) {
  // do some calculations
}

最初のスニペットでは、すべてのプロミスが同時に実行されることを知っていますが、2番目のスニペットについてはわかりません。 forループは、次のpromiseを呼び出すために最初の反復が完了するまで待機しますか?または、すべてのプロミスが同時に実行され、ループの内側がコールバックのように機能しますか?

4
NicoAdrian

実際、for await構文を使用すると、promiseが一度に実行されます。

小さなコードがそれを証明します:

const sleep = s => {
  return new Promise(resolve => {
    setTimeout(resolve, s * 1000);
  });
}

const somethingAsync = async t => {
  await sleep(t);
  return t;
}

(async () => {
  const items = [1, 2, 3, 4];
  const now = Date.now();
  for await (const res of items.map(e => somethingAsync(e))) {
    console.log(res);
  }
  console.log("time: ", (Date.now() - now) / 1000);
})();

stdout:time: 4.001

しかし、ループの内側は「コールバック」として機能しません。配列を逆にすると、すべてのログが一度に表示されます。 promiseがすぐに実行され、ランタイムは最初のものが解決して次の反復に進むのを待つだけだと思います。

編集:実際、for awaitを非同期イテレータ以外で使用する場合、Promise.allを使用することはお勧めできません。

0
NicoAdrian