≪ Today I learned.
RSS購読
    公開日
    タグ
    JavaScript
    著者
    ダーシノ

    Promiseの静的メソッド(all/allSettled/any/race)の違いを理解する

    JavaScriptで非同期処理に使うPromiseオブジェクトには、以下のような静的メソッドがある。

    Promise.all()はよく使うものの他はあまり使ったことがないので、すぐ使い方を忘れてしまう。そこで、ユースケースと視覚的にわかりやすく解説する。

    Promiseの静的メソッドの違い

    Promise.all()

    Promise.all()は、引数に渡したPromiseオブジェクトがすべてResolveするまで待つ。ただし、ひとつでも失敗すると即座にRejectする。

    依存関係のあるデータの並行取得などで使う。

    try {
      const [fetchTeams, fetchUsers] = await Promise.all([
        fetch('/api/teams'),
        fetch('/api/users'),
      ])
    } catch (e) {
      window.alert('データの取得に失敗しました。')
    }

    Promise.allSettled()

    Promise.allSettled()は、引数に渡したPromiseオブジェクトが成功、失敗問わずにすべて完了するまで待つ。失敗してもエラーを投げない。

    エラーも含めて集計するときなどで使う。

    const results = await Promise.allSettled([
      fetch('/api/status'),
      fetch('/api/schedules'),
    ])
    
    const hasSomeError = results.some(result => result.status === 'rejected')

    Promise.any()

    Promise.any()は、引数に渡したPromiseオブジェクトのうち、ひとつでもResolveすれば成功とみなす。ただし、すべてRejectするとAggregateErrorを投げる。

    複数あるミラーやフォールバックのうち最初に成功したものだけで十分なときなどで使う。

    try {
      const data = await Promise.any([
        fetch('/mirror/tokyo/items'),
        fetch('/mirror/nagoya/items'),
        fetch('/mirror/osaka/items'),
      ])
    
      console.log('データの取得に成功しました。', data)
    
    } catch (e) {
      window.alert('データの取得に失敗しました。')
    }

    Promise.race()

    Promise.race()は、引数に渡したPromiseオブジェクトのうち、最初にResolveしたものを採用する。成功しても失敗しても、最初に完了したものが結果になる。

    タイムアウト処理の実装などで使う。

    const waitForUserAction = ...
    const timeout = (ms: number) => ...
    
    await Promise.race([
      waitForUserAction(),
      timeout(60 * 1000),
    ])

    デモ

    Promise静的メソッドのデモ

      Promiseの実行方法