JavaScriptのPromise.allとは?複数の非同期処理をまとめて実行する方法

複数のデータが同時に集まり、一つの結果に統合される様子を表した抽象的なデジタルイメージ
複数の非同期処理を並列実行し、結果をまとめて取得するPromise.allのイメージ

JavaScriptで非同期処理を扱う際、「複数の処理を同時に実行して、すべて完了したタイミングで結果を受け取りたい」という場面は非常に多くあります。そのようなケースで活躍するのが Promise.all です。

この記事では、Promise.allの基本から実務での使い方、注意点までを体系的に解説します。非同期処理の理解を一段階深めたい場合にも役立つ内容です。

Promise.allとは

Promise.allは、複数のPromiseをまとめて実行し、すべてが成功したときに結果をまとめて返すメソッドです。

Promise.all([promise1, promise2, promise3]);

配列に複数のPromiseを渡すことで、それらを並列に実行できます。

Promise.allの基本的な使い方

複数の非同期処理を同時に実行する

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

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

ポイント

  • 配列の順番通りに結果が返る
  • すべて成功した場合のみthenが実行される
  • 1つでも失敗するとcatchに進む

Promise.allの仕組み

Promise.allは以下のように動作します。

すべて成功した場合

  • 全Promiseが「fulfilled」になるまで待機
  • すべての結果を配列で返す

1つでも失敗した場合

  • 最初に失敗したPromiseの時点で処理終了
  • catchにエラーが渡る
const promise1 = Promise.resolve("成功");
const promise2 = Promise.reject("失敗");

Promise.all([promise1, promise2])
  .then((results) => {
    console.log(results);
  })
  .catch((error) => {
    console.error(error); // "失敗"
  });

async/awaitとPromise.allの組み合わせ

Promise.allはasync/awaitと組み合わせることで、より読みやすいコードになります。

async function fetchData() {
  const promise1 = Promise.resolve("データ1");
  const promise2 = Promise.resolve("データ2");

  try {
    const results = await Promise.all([promise1, promise2]);
    console.log(results); // ["データ1", "データ2"]
  } catch (error) {
    console.error(error);
  }
}

fetchData();

メリット

  • コードが直感的になる
  • エラーハンドリングがしやすい

実務でよくある使い方

APIを同時に複数呼び出す

async function fetchUsersAndPosts() {
  const usersPromise = fetch("https://jsonplaceholder.typicode.com/users")
    .then((res) => res.json());

  const postsPromise = fetch("https://jsonplaceholder.typicode.com/posts")
    .then((res) => res.json());

  const [users, posts] = await Promise.all([usersPromise, postsPromise]);

  console.log(users);
  console.log(posts);
}

fetchUsersAndPosts();

ポイント

  • 並列処理により高速化できる
  • 順番にawaitするより効率が良い

Promise.allを使うべき場面

Promise.allは以下のようなケースで適しています。

  • 複数の非同期処理を同時に実行したい
  • すべての結果が揃ってから次の処理を行いたい
  • 処理の順序よりも速度を優先したい

Promise.allの注意点

1つでも失敗すると全体が失敗する

const p1 = Promise.resolve(1);
const p2 = Promise.reject("エラー");
const p3 = Promise.resolve(3);

Promise.all([p1, p2, p3])
  .then((res) => console.log(res))
  .catch((err) => console.error(err));

この場合、p2の時点で全体が失敗扱いになります。

個別にエラーを処理したい場合

その場合は、各Promiseでエラーを吸収します。

const p1 = Promise.resolve(1);
const p2 = Promise.reject("エラー").catch(() => null);
const p3 = Promise.resolve(3);

Promise.all([p1, p2, p3])
  .then((results) => {
    console.log(results); // [1, null, 3]
  });

Promise.allとPromise.allSettledの違い

Promise.allと似たメソッドにPromise.allSettledがあります。

Promise.all

  • 1つでも失敗すると全体が失敗

Promise.allSettled

  • 成功・失敗に関係なくすべての結果を返す
Promise.allSettled([
  Promise.resolve(1),
  Promise.reject("エラー"),
])
.then((results) => {
  console.log(results);
});

Promise.allのよくあるミス

Promiseを渡していない

// NG例
Promise.all([
  fetch("url1"),
  fetch("url2")
]);

これは問題ないように見えますが、thenやawaitで結果を扱わないと意味がありません。

正しい例

async function loadData() {
  const responses = await Promise.all([
    fetch("https://jsonplaceholder.typicode.com/posts"),
    fetch("https://jsonplaceholder.typicode.com/comments")
  ]);

  const data = await Promise.all(responses.map((res) => res.json()));

  console.log(data);
}

loadData();

まとめ

Promise.allは、複数の非同期処理を効率よく扱うための重要なメソッドです。

  • 複数のPromiseを並列実行できる
  • すべて成功した場合のみ結果を取得できる
  • async/awaitと組み合わせると可読性が向上する
  • エラー時の挙動には注意が必要

非同期処理を正しく理解することで、パフォーマンスとコード品質の両方を向上させることができます。

関連記事