はじめに
JavaScriptの非同期処理を適切に扱うことはパフォーマンス向上の鍵となります。本記事では、Promise.all
を活用した並列処理について解説し、どのようにして API リクエストのパフォーマンスを改善できるのかを紹介します。
Promise.all
の基本
通常、await
を使った非同期処理は逐次実行されるため、複数のリクエストを順番に処理すると全体の実行時間が長くなってしまいます。
そのため、データ間に依存関係がない場合は、並列にデータ取得を行うことでパフォーマンスが効率的になります。
例えば、以下のコードでは getUserProfile
の処理が完了してから getUserPosts
が実行されるため、両者の合計時間がかかってしまいます。
const userProfile = await getUserProfile(userId);
const userPosts = await getUserPosts(userId);
これを Promise.all
を使うことで、両方のリクエストを並列して実行し、パフォーマンスを向上させることができます。
Promise.all
を使った並列処理
以下のように Promise.all
を使用することで、getUserProfile
と getUserPosts
を同時に実行し、両者の完了を待つことができます。
const [profile, posts] = await Promise.all([
getUserProfile(userId),
getUserPosts(userId),
]);
これにより、個々の処理を逐次実行するよりも高速にデータを取得できます。
実行時間の比較
-
逐次実行 (順番に実行):
getUserProfile
に 500ms、getUserPosts
に 800ms かかる場合、合計 1300ms かかる。 -
並列実行 (
Promise.all
): どちらも同時に開始されるため、最大時間である 800ms で完了。
つまり、Promise.all
を使用することで処理時間を短縮できます。
以下の画像は、Next.jsの公式ドキュメントにあるデータ取得の逐次実行と並列実行によるパフォーマンスのイメージ図です。
Promise.all
の注意点
Promise.all
を使う際には、以下の点に注意が必要です。
-
いずれかの処理が失敗すると全体が失敗する
-
Promise.all
はすべてのプロミスが成功するまで待機しますが、一つでもエラーが発生すると即座にcatch
に入り、他のプロミスの結果を取得できません。 - 対策:
Promise.allSettled
を使用することで、すべての処理の結果を取得可能。
const results = await Promise.allSettled([ getUserProfile(userId), getUserPosts(userId), ]); results.forEach((result) => { if (result.status === "fulfilled") { console.log("Success:", result.value); } else { console.error("Error:", result.reason); } });
-
-
API に負荷をかけすぎないようにする
-
Promise.all
はすべての処理を並列実行するため、一度に大量のリクエストを送るとサーバーに負荷をかける可能性があります。 - 対策:
p-limit
などのライブラリを使用して同時リクエスト数を制御する。
-
まとめ
Promise.all
を活用することで、複数の非同期処理を並列実行し、パフォーマンスを大幅に向上させることができます。
本記事が Promise.all
を活用した効率的な非同期処理の実装に役立てば幸いです。