複数の非同期処理の統合 | Promise.allとPromise.race | JavaScript 超完全入門 基本から発展までのすべて

スポンサーリンク
スポンサーリンク
amazon
スマイルSALE
--:--:--
ad. 価格範囲を指定して商品を探せます

複数の非同期処理を統合するには?

JavaScriptで複数の非同期処理をまとめて扱う場合、Promise.allPromise.racePromise.allSettledなどを使用できます。

これらを使うことで、複数の通信処理をまとめて実行したり、すべての処理が終わるのを待ったり、最初に完了した処理だけを利用したりできます。

非同期処理を適切に統合できると、API通信やファイル読み込みなどを効率よく管理できます。

Promise.allとは?

Promise.all()は、複数の非同期処理がすべて成功するまで待つためのメソッドです。

すべてのPromiseが成功すると、結果が配列として返されます。一方で、どれか1つでも失敗すると、その時点でcatchが実行されます。

Promise.allの使用例

const promise1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("データ1取得完了");
    }, 1000);
});

const promise2 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("データ2取得完了");
    }, 2000);
});

const promise3 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("データ3取得完了");
    }, 3000);
});

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

この例では、3つの非同期処理がすべて完了した後にthenが実行されます。

実行結果は、次のようになります。

[
    "データ1取得完了",
    "データ2取得完了",
    "データ3取得完了"
]

Promise.all()の結果は、完了した順番ではなく、配列に指定した順番で返されます。

Promise.raceとは?

Promise.race()は、複数の非同期処理のうち、最初に完了したPromiseの結果だけを取得するメソッドです。

最初に完了したPromiseが成功すればthenが実行され、失敗すればcatchが実行されます。

Promise.raceの使用例

const promise1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("データ1取得完了");
    }, 1000);
});

const promise2 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("データ2取得完了");
    }, 2000);
});

const promise3 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("データ3取得完了");
    }, 3000);
});

Promise.race([promise1, promise2, promise3])
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.error(error);
    });

この例では、最も早く完了するpromise1の結果が取得されます。

データ1取得完了

なお、Promise.race()で最初の結果が返された後も、他のPromiseの処理自体が自動的にキャンセルされるわけではありません。結果として利用されないだけです。

Promise.allとPromise.raceの違い

Promise.all()Promise.race()の違いをまとめると、次のようになります。

特徴 Promise.all Promise.race
処理の終了タイミング すべての非同期処理が成功したとき。 最初の非同期処理が完了したとき。
成功・失敗の扱い 1つでも失敗すると全体が失敗する。 最初に完了したPromiseの結果で成功・失敗が決まる。
結果 すべての結果が配列で返る。 最初に完了したPromiseの結果だけが返る。
主な用途 複数のデータをすべて取得したい場合。 タイムアウト処理や最速の結果を使いたい場合。

Promise.allSettledとは?

Promise.allSettled()は、複数の非同期処理が成功・失敗に関係なくすべて完了するまで待つメソッドです。

Promise.all()は1つでも失敗するとcatchへ移動しますが、Promise.allSettled()はすべての結果を確認できます。

Promise.allSettledの使用例

const promise1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve("データ1取得完了");
    }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("データ2取得失敗");
    }, 2000);
});

Promise.allSettled([promise1, promise2])
    .then((results) => {
        console.log(results);
    });

実行結果は、次のような形式になります。

[
    {
        status: "fulfilled",
        value: "データ1取得完了"
    },
    {
        status: "rejected",
        reason: "データ2取得失敗"
    }
]

fulfilledは成功、rejectedは失敗を表します。

async/awaitと組み合わせる

現在のJavaScriptでは、Promise.all()などをasync/awaitと組み合わせて使うことも多くあります。

Promise.allとasync/awaitの例

async function fetchAllData() {
    try {
        const results = await Promise.all([
            fetch("/api/user").then((response) => response.json()),
            fetch("/api/posts").then((response) => response.json())
        ]);

        console.log(results);
    } catch (error) {
        console.error("データ取得に失敗しました:", error);
    }
}

fetchAllData();

この例では、ユーザー情報と投稿情報を並行して取得しています。順番にawaitするよりも、同時に開始できるため効率的です。

Promise.anyとは?

Promise.any()は、複数のPromiseのうち、最初に成功したPromiseの結果を返すメソッドです。

Promise.race()は最初に完了したPromiseが失敗すると全体も失敗しますが、Promise.any()は失敗したPromiseを無視し、最初に成功した結果を待ちます。

Promise.any([
    Promise.reject("失敗1"),
    Promise.resolve("成功"),
    Promise.reject("失敗2")
])
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.error(error);
    });

この例では、最初に成功した"成功"が結果として取得されます。

使い分けの目安

メソッド 使う場面
Promise.all() すべての処理が成功する必要がある場合。
Promise.allSettled() 成功・失敗に関係なく、すべての結果を確認したい場合。
Promise.race() 最初に完了した処理だけを使いたい場合。
Promise.any() 最初に成功した結果だけを使いたい場合。

まとめ

  • 複数の非同期処理を統合するには、Promise.all()Promise.race()Promise.allSettled()などを使います。
  • Promise.all()は、すべてのPromiseが成功したときに結果を配列で返します。
  • Promise.race()は、最初に完了したPromiseの結果だけを返します。
  • Promise.allSettled()は、成功・失敗に関係なくすべての結果を取得できます。
  • Promise.any()は、最初に成功したPromiseの結果を返します。
  • async/awaitと組み合わせると、複数の非同期処理を読みやすく管理できます。
  • 用途に応じてメソッドを使い分けることで、効率的な非同期処理を書けます。