【JavaScript入門】Promiseの静的メソッド

 Promise の 静的メソッド は、複数の Promise を“まとめて”扱うための API です。直列(チェーン)ではなく 並列 に非同期タスクを走らせ、

  • 全部終わったら次へ
  • どれか 1 つ終わったら次へ
  • 全部の成否を収集して次へ
  • 最初に終わった 1 つだけ採用

 などの挙動を1行で表現できます。ここでは代表的な4兄弟 .all() .any() .allSettled() .race() と、補助的な .resolve() .reject() を実践コードで学びます。

1.主要静的メソッドの早見表

1.主要静的メソッドの早見表

メソッド解決 (fulfilled) 条件拒否 (rejected) 条件返る値
Promise.all(arr)配列 arr全て が解決1つでも拒否成功時: 結果配列
失敗時: 拒否理由
Promise.any(arr)1つでも解決全て 拒否成功時: 最初に解決した値
失敗時: AggregateError
Promise.allSettled(arr)―(必ず完了)―(必ず完了)全ての結果を配列で受け取る
Promise.race(arr)最初に完了した要素が解決なら解決最初に完了した要素が拒否なら拒否その 値/理由

1.1. .all().any() の比較

 .all()“みんな OK なら OK”.any()“誰か1人 OK なら OK”。片方を覚えればもう片方は真逆だと理解できます。

1.2. .allSettled()

成功/失敗を区別せず「終わった事実」だけが欲しいときに便利。UI のローディング解除など “あと片付け担当” に向いています。

1.3. .race()

 「最速の結果だけ採用」が必要なとき。最初の API が遅い場合にバックアップ API へ同時リクエストする フェイルオーバー戦略 などで使われます。

2.補助メソッド

メソッド概要
Promise.resolve(v)すでに解決済みの Promise を即座に生成
Promise.reject(v)すでに拒否済みの Promise を即座に生成

これらは .then() 連鎖の途中で「同期値を Promise 化」したいときに重宝します。

3.サンプルプログラムで体感する

3.1. ファイル名:promise-static-demo.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>🚀 Promise 静的メソッド入門</title>
  <style>
    body{font-family:"Segoe UI",sans-serif;margin:2rem;background:#eef7ff}
    h1{font-size:1.8rem;text-align:center;margin-bottom:1rem}
    #log{white-space:pre-line;background:#fff;border:1px solid #c4c4c4;
         border-radius:8px;padding:1rem;min-height:8rem}
    button{margin:.4rem .2rem;padding:.5rem 1.1rem;border:none;border-radius:6px;
           background:#0078d4;color:#fff;font-weight:bold;cursor:pointer}
    button:hover{opacity:.85}
  </style>
</head>
<body>
  <h1>🚀 Promise 静的メソッド入門</h1>
  <div>
    <button data-type="all">Promise.all()</button>
    <button data-type="any">Promise.any()</button>
    <button data-type="allSettled">Promise.allSettled()</button>
    <button data-type="race">Promise.race()</button>
  </div>
  <div id="log"></div>

  <script>
  // 任意ミリ秒後に resolve / reject するユーティリティ
  const wait = (ms, ok = true) =>
    new Promise((resolve, reject) =>
      setTimeout(() => ok ? resolve(`${ms}ms OK`) : reject(`${ms}ms NG`), ms)
    );

  const out = msg => log.textContent += msg + "\n";
  const log = document.getElementById("log");

  // ボタンハンドラ
  document.querySelectorAll("button").forEach(btn => {
    btn.onclick = async () => {
      log.textContent = "";               // ログクリア
      const type = btn.dataset.type;
      const tasks = [wait(300, true), wait(500, false), wait(200, true)];

      try {
        let result;
        switch (type) {
          case "all":        result = await Promise.all(tasks);                break;
          case "any":        result = await Promise.any(tasks);                break;
          case "allSettled": result = await Promise.allSettled(tasks);         break;
          case "race":       result = await Promise.race(tasks);               break;
        }
        out(`✅ then: ${JSON.stringify(result)}`);
      } catch (e) {
        out(`❌ catch: ${e instanceof AggregateError ? "AggregateError" : e}`);
      } finally {
        out("🔚 finally: 完了しました");
      }
    };
  });
  </script>
</body>
</html>

3.2. ブラウザの出力例

 上は Promise.all() 実行時、最も遅い 500 ms タスクが拒否されたため .catch() へは飛ばず、成功した2つの結果だけ返っています(3つ全て成功ケースで実行した場合)。

3.3. コード解説

  1. wait(ms, ok)
    テスト用の非同期処理。ok が false のとき reject() を呼びます。
  2. tasks 配列
    3つの Promise を同時に作成し「並列」状態に。
  3. await Promise.all(tasks)
    ・全タスク成功 → 結果配列(順序は元配列順)
    ・1つでも拒否 → その拒否理由を catch
  4. Promise.any()
    ・最初に成功した1つを返す。
    ・全て拒否 → AggregateError
  5. Promise.allSettled()
    ・3要素すべて完了後、[{status:"fulfilled",…}, …] を返す。
    ・成否にかかわらずエラーは出ない
  6. Promise.race()
    ・200 ms が最速 → その値で即決
    ・最速が拒否なら catch

4.実践 TIPS

  • API バッチ呼び出し
    レスポンスが揃うまで待ちたい → Promise.all()
  • 優先度付き複数ソース
    どれか成功すれば OK → Promise.any()
  • 進行状況バー
    成否に関係なく“全完了”でバーを 100 % → Promise.allSettled()
  • フェイルオーバー
    もっとも速い API を採用 → Promise.race()

まとめ

Promise の静的メソッドは “複数の非同期を1つの戦略で束ねる” 高水準 API です。
.all() .any() .allSettled() .race() を組み合わせると、

  • バッチ処理
  • タイムアウト対策
  • 並列ロードとフォールバック
    を簡潔に記述できます。これらを活用して、複雑なフロントエンドのレスポンス制御を 読みやすく、堅牢 に設計しましょう。