複数の非同期リクエストの処理
メニューを表示するにはスワイプしてください
多くの実際のアプリケーションでは、複数の非同期タスクを同時に実行したり、どちらが先に完了するかを判断したりする必要があります。JavaScript では、このような状況に対応するために、Promise.all() と Promise.race() という2つの主要なメソッドが用意されています。
Promise.all(): 並列でのタスク実行
Promise.all() を使用すると、複数のプロミスを並列で実行できます。これは、配列内のすべてのプロミスが解決されたときに1つのプロミスとして解決され、いずれか1つでも拒否されるとすぐに拒否されます。すべての非同期処理が正常に完了してから次に進みたい場合に便利です。
index.html
index.js
fetchMultipleResources 関数は、投稿、ユーザー、およびコメントデータを同時に取得するために3つのリクエストを送信します。Promise.all() を使用することで、3つのリクエストが同時に開始され、すべてのプロミスが解決されるまで待機します。解決後、結果はそれぞれの変数(post、user、comments)に分割されます。投稿タイトル、ユーザー名、コメントの総数が HTML に表示されます。この方法は、すべてのリクエストが完了してから処理を進める必要がある場合に効率的であり、タスクを並行して実行することで全体の待機時間を短縮します。
Promise.race(): 最初に解決されたプロミスの処理
Promise.race() は、配列内の最初のプロミスが解決または拒否された時点で、その結果に応じて解決または拒否される単一のプロミスを返します。これは、最も早い結果が必要な場合や、リクエストが長時間かかる場合にタイムアウト処理を行いたい場合に有用です。
index.html
index.js
fetchWithTimeout 関数は、3秒後に拒否される timeoutPromise を作成し、タイムアウトをシミュレートします。同時に、fetchPromise がAPIからデータをリクエストします。Promise.race() を使用することで、どちらか早く完了したプロミスの結果を待ちます。フェッチが3秒以内に完了すれば、投稿タイトルが表示されます。逆に、フェッチに時間がかかりすぎた場合はタイムアウトが発生し、HTMLにエラーメッセージ(「Request timed out!」)が表示されます。この方法は、迅速な応答が求められる状況に最適です。
並列リクエストと逐次リクエストの利用ケース
並列リクエスト(Promise.all())を使う場合
複数の独立したデータソースからデータを取得する場合、すべてのリクエストを同時に実行できるため、並列リクエストが最適です。例えば、ダッシュボードでユーザーデータ、投稿、コメントを読み込む場合、それぞれのリクエストは独立しており、同時に取得することでパフォーマンスが向上します。この方法では、リクエストが順番に処理されるのではなく同時に処理されるため、待ち時間を最小限に抑えることができます。
逐次リクエストを使う場合
タスクを特定の順序で完了する必要がある場合、つまり1つが終わってから次を始める必要がある場合は、逐次リクエストが必要です。このような依存関係のあるリクエストには、ループ内で async/await を使うか、.then() をチェーンして Promise.all() を避けます。
例えば、最初にユーザーデータを取得し、その取得したユーザーIDを使ってユーザーの投稿を取得する場合です。このようなケースでは、それぞれのリクエストが前の結果に依存しているため、逐次的なアプローチが必要となります。
index.html
index.js
この例は、各リクエストが前のリクエストの結果に依存する場合の逐次リクエストの実行方法を示しています。fetchUserDataSequentially では、最初にAPIからユーザーデータを取得します。ユーザーデータを受け取り解析した後、ユーザーIDを使って2回目のリクエストでユーザーの投稿データを取得します。結果はHTMLに表示され、ユーザー名と投稿数が示されます。この逐次的なアプローチは、リクエスト同士が依存関係にある場合に必要であり、各リクエストが完了してから次のリクエストを開始することを保証します。
1. Promise.all() に Promise の配列を渡すと何が起こりますか?
2. 他の Promise の状態に関係なく、最も早く解決された Promise を取得するにはどのメソッドを使いますか?
フィードバックありがとうございます!
AIに質問する
AIに質問する
何でも質問するか、提案された質問の1つを試してチャットを始めてください