フロントエンド開発において、Promise.all は並列処理の代名詞ですが、実際の業務では「順序を守る」ことが求められる場面が多々あります。例えば、リスト内の各アイテムに対して API を叩き、その結果に基づいて連続的に DOM を更新したり、順番にサーバーへデータを送信したりする場合です。ここで活躍するのが for await…of です。
for await…of の本質とは
for await…of は、非同期イテレータを扱うための構文です。これを使うことで、非同期処理を「同期処理のような直感的なコード」で記述できます。例えば、非同期関数を格納した配列を扱う際、forEach を使ってしまうと、各コールバック関数が並行して実行されてしまい、意図しないレースコンディション(競合)を引き起こす可能性があります。for await…of を使えば、前のループの完了を待ってから次の処理へ移行するため、安全なシーケンシャル処理が可能です。
業務での具体的活用シーン:順次リクエストと進捗表示
実務で最も恩恵を感じるのは、大量のファイルをアップロードする際や、段階的なデータ更新を行う処理です。
例えば、画像アップロード機能で「1枚ずつアップロードし、成功したら進捗バーを更新する」という要件があるとします。Promise.all を使うと一気にリクエストが飛んでしまい、サーバー負荷が高まるだけでなく、進捗の順序も保証されません。
ここで for await…of を使い、生成した Promise の配列を順次解決させることで、UI 上の進捗を正確に制御できます。「並列化による速度」よりも「制御による確実性」が優先されるシーンこそが、この構文の適所です。
避けるべきアンチパターンと注意点
ただし、なんでもかんでも for await…of で書くのは危険です。最大の注意点は「パフォーマンスの低下」です。すべての処理を直列化してしまうと、本来並列に実行できたはずの API リクエストまで待機時間が生じ、ユーザー体験を損なう可能性があります。
また、エラーハンドリングにも注意が必要です。for await…of 内で例外が発生した場合、そのループは即座に停止します。途中で失敗しても残りの処理を継続したい場合は、ループの中で個別に try-catch を配置する必要があります。
まとめ
for await…of は、非同期処理を「流れ」として制御するための強力なツールです。Promise.all との使い分けを意識し、「並列でいいのか、それとも順序が重要なのか」を設計段階で見極めることが、フロントエンド・エンジニアとしての腕の見せ所です。コードの可読性を高めつつ、堅牢な非同期フローを構築するために、ぜひこの「待つループ」を武器にしてください。