JavaScript | 第14章「プロミスの使用」

javascrpit JavaScript
スポンサーリンク

ここではステップ課題の 模範解答 と、Promise の内部の流れを 図解+アニメーション風に解説 します。
Promise の「状態変化」と「then チェーンのつながり」がイメージできるようにします。

課題:wait(ms) 関数を作って、順に待つ

模範解答

// 「msミリ秒後にresolveするPromise」を返す関数
function wait(ms) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(`✅ ${ms}ms 経過`);
    }, ms);
  });
}

// Promise チェーンで順に待つ
wait(1000)
  .then(msg => {
    console.log(msg); // ✅ 1000ms 経過
    return wait(2000);
  })
  .then(msg => {
    console.log(msg); // ✅ 2000ms 経過
    return wait(3000);
  })
  .then(msg => {
    console.log(msg); // ✅ 3000ms 経過
  })
  .finally(() => {
    console.log("🎉 すべて完了!");
  });
JavaScript

図解:Promise の流れ

1️⃣ まず「wait(1000)」が呼ばれる

Promise(wait(1000))  ──> [ pending ](保留中)
  ↓ 1秒後
Promise(wait(1000))  ──> [ fulfilled ](成功)
  値: "✅ 1000ms 経過"
JavaScript

resolve() が呼ばれた時点で .then() に値が渡ります。

2️⃣ thenチェーンで「次のPromise」を返す

.then(msg => return wait(2000))
JavaScript

これにより:

Promise(wait(2000))  ──> [ pending ]
  ↓ 2秒後
Promise(wait(2000))  ──> [ fulfilled ]
  値: "✅ 2000ms 経過"
JavaScript

「thenの戻り値がPromiseなら、次のthenはその結果を待つ」

3️⃣ さらにチェーン(3秒待ち)

.then(msg => return wait(3000))
JavaScript
Promise(wait(3000)) ──> [ pending ]
  ↓ 3秒後
Promise(wait(3000)) ──> [ fulfilled ]
  値: "✅ 3000ms 経過"
JavaScript

4️⃣ 最後の .finally()

.finally(() => console.log("🎉 すべて完了!"))
JavaScript

finally は成功・失敗に関係なく、
「チェーンが落ち着いたあとに必ず実行」 されます。

アニメーション風イメージ

wait(1000) 開始
⏳ ・・・1秒後・・・
✅ 1000ms 経過

wait(2000) 開始
⏳ ・・・2秒後・・・
✅ 2000ms 経過

wait(3000) 開始
⏳ ・・・3秒後・・・
✅ 3000ms 経過

🎉 すべて完了!
JavaScript

Promiseチェーンの仕組み(内部の動き)

Promise #1 ──.then()──▶ Promise #2 ──.then()──▶ Promise #3 ──.finally()
JavaScript

それぞれの .then()新しい Promise を返している のがポイント。
つまり:

thenの中の戻り値次のPromiseの状態
通常の値fulfilled(成功)
Promiseを返すそのPromiseの状態を引き継ぐ
例外throwrejected(失敗)

よくある誤解ポイント

then() の中で Promiseを返さない と、
次の処理が「待たずに進む」ことがあります。

例:

wait(1000)
  .then(() => {
    console.log("1000ms経過");
    wait(2000); // ← return を忘れている!
  })
  .then(() => {
    console.log("この行は即実行される!");
  });
JavaScript

✅ 修正版:

wait(1000)
  .then(() => {
    console.log("1000ms経過");
    return wait(2000); // return を書く!
  })
  .then(() => {
    console.log("2000ms 待ったあとに実行");
  });
JavaScript

補足:async / await 版(Promiseを「同期的に見せる」)

同じ処理を async / await で書くとこうなります。

function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function run() {
  await wait(1000);
  console.log("✅ 1秒経過");

  await wait(2000);
  console.log("✅ さらに2秒経過");

  await wait(3000);
  console.log("✅ さらに3秒経過");

  console.log("🎉 すべて完了!");
}

run();
JavaScript

これも中身は Promise チェーンと同じ動き
await は「Promise の結果を待ってから次に進む」という糖衣構文です。

まとめ図

┌────────────┐
wait(1000) │
└────┬───────┘
resolve("1s経過")

┌────────────┐
wait(2000) │
└────┬───────┘
resolve("2s経過")

┌────────────┐
wait(3000) │
└────┬───────┘
resolve("3s経過")

🎉 finally() 実行!
JavaScript
タイトルとURLをコピーしました