JavaScript 非同期 forEach

Shraddha Paghdar 2023年6月20日
JavaScript 非同期 forEach

今日の投稿では、JavaScript の forEach ループで async を使用できるかどうかを見ていきます。 代替手段は何ですか?

JavaScript の非同期 forEach

非同期プログラミングは、Array.prototype.forEach を対象としていません。 promise の場合と同様に、async-await には不適切です。

const employees = await this.getEmployees();

// BAD
await employees.forEach(async (employee) => {
  await giveBonusToEmployee(employee);
});

await sendEmail('All bonuses sent');

これにはいくつかの問題があります:

  1. 返された iterator 関数の promise は処理されません。 したがって、そのうちの 1つがエラーを起こしても気付かれません。 ノード 10 に unhandledrejection リスナーが登録されていない場合、プロセスはクラッシュします。
  2. forEach は各プロミスが 1つずつ満たされるのを待たないため、すべてのボーナスは順次ではなく同時に配布されます。 その結果、すべてのボーナスが与えられる前にループが終了します。
  3. その結果、ボーナスが完全に提供される前に、sendEmail() がメールを送信します。 おそらく何も配られないでしょう。 それらはすべてエラーをスローする可能性があります!

以下は、これに対して実装できるソリューションです。

  1. 各ボーナスを順番に処理します。 JavaScript が async-await をサポートしているため、for...of 構造を使用できます。
for (const employee of employees) {
  await giveBonusToEmployee(employee);
}

次のボーナスに移る前に、このループは前のボーナスが配られるのを待ちます。 必要以上に冗長になりますが、この状況では典型的な for(...;...;...) を使用することもできます。

  1. すべてのボーナスを並行して処理します。
await Promise.all(employees.map(async (employee) => {
  await giveBonusToEmployee(employee);
}));

順序が重要でない場合は、すべての従業員を同時に分析する方が迅速な場合があります。 これにより、すべてのボーナスが一度に配布され始めますが、すべてのボーナスが送信されるまで sendEmail() は実行されません。

forwhile ループは、元の関数本体に記述されているため、async-await で自然に動作します。 ただし、別の関数を呼び出す場合、呼び出された関数が promise を返し、その promise を処理する場合にのみ、async-await を使用できます。

.reduce().map() の両方がプロミスまたはプロミスの配列を生成するため、await を使用できます。

ただし、ほとんどの配列メソッドは promise を返さないか、ある呼び出しから別の呼び出しに promise を渡すことができないため、それらを非同期で使用することはできません。 その結果、非同期コードを配列内で使用することはできません。たとえば、array.some()array.filter() などです。

Shraddha Paghdar avatar Shraddha Paghdar avatar

Shraddha is a JavaScript nerd that utilises it for everything from experimenting to assisting individuals and businesses with day-to-day operations and business growth. She is a writer, chef, and computer programmer. As a senior MEAN/MERN stack developer and project manager with more than 4 years of experience in this sector, she now handles multiple projects. She has been producing technical writing for at least a year and a half. She enjoys coming up with fresh, innovative ideas.

LinkedIn

関連記事 - JavaScript Async

関連記事 - JavaScript Loop