JavaScriptの非同期処理で複数のPromiseを効率的に管理したい場合、`Promise.all()`メソッドを使用することで並列処理を実現できます。この記事では、`Promise.all()`の基本的な使い方から実践的な例まで、詳しく解説します。

Promise.all()とは

`Promise.all()`は、複数のPromiseをまとめて処理し、すべてのPromiseが解決(fulfilled)されるのを待つメソッドです。配列で渡された全てのPromiseが成功した場合にのみ、結果を配列として返します。

基本的な使い方

const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
  .then(values => {
    console.log(values); // [1, 2, 3]
  })
  .catch(error => {
    console.error(error);
  });

実践的な使用例

APIから複数のデータを取得する

const fetchUsers = () => fetch('https://api.example.com/users');
const fetchPosts = () => fetch('https://api.example.com/posts');
const fetchComments = () => fetch('https://api.example.com/comments');

Promise.all([fetchUsers(), fetchPosts(), fetchComments()])
  .then(responses => Promise.all(responses.map(res => res.json())))
  .then(data => {
    const [users, posts, comments] = data;
    console.log('Users:', users);
    console.log('Posts:', posts);
    console.log('Comments:', comments);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

エラーハンドリング

`Promise.all()`は、いずれかのPromiseが失敗(reject)した場合、即座にエラーを返します。

const promise1 = Promise.resolve(1);
const promise2 = Promise.reject('エラーが発生しました');
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
  .then(values => {
    console.log(values);
  })
  .catch(error => {
    console.error(error); // "エラーが発生しました"
  });

async/awaitでの使用

より読みやすいコードを書くために、async/awaitと組み合わせることができます。

async function fetchAllData() {
  try {
    const results = await Promise.all([
      fetch('https://api.example.com/users'),
      fetch('https://api.example.com/posts'),
      fetch('https://api.example.com/comments')
    ]);
    
    const data = await Promise.all(results.map(res => res.json()));
    return data;
  } catch (error) {
    console.error('エラーが発生しました:', error);
    throw error;
  }
}

パフォーマンスの注意点

  • 全てのPromiseは並列で実行されるため、個別に実行するよりも効率的です
  • ただし、一つでも失敗すると全体が失敗となるため、エラーハンドリングは慎重に行う必要があります
  • メモリ使用量に注意が必要で、大量のPromiseを同時に実行する場合は注意が必要です

代替手段

  • `Promise.allSettled()`: すべてのPromiseの結果(成功・失敗)を待つ
  • `Promise.race()`: 最初に解決されたPromiseの結果を返す
  • `Promise.any()`: 最初に成功したPromiseの結果を返す

まとめ

`Promise.all()`は、複数の非同期処理を効率的に管理するための強力なツールです。APIリクエストや並列処理が必要な場合に特に有用です。適切なエラーハンドリングと使用方法を理解することで、より効率的な非同期処理を実装できます。

上記の例と説明を参考に、あなたのプロジェクトで`Promise.all()`を活用してみてください。