ここではステップ課題の 模範解答 と、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))
JavaScriptPromise(wait(3000)) ──> [ pending ]
↓ 3秒後
Promise(wait(3000)) ──> [ fulfilled ]
値: "✅ 3000ms 経過"
JavaScript4️⃣ 最後の .finally()
.finally(() => console.log("🎉 すべて完了!"))
JavaScriptfinally は成功・失敗に関係なく、
「チェーンが落ち着いたあとに必ず実行」 されます。
アニメーション風イメージ
▶ wait(1000) 開始
⏳ ・・・1秒後・・・
✅ 1000ms 経過
↓
▶ wait(2000) 開始
⏳ ・・・2秒後・・・
✅ 2000ms 経過
↓
▶ wait(3000) 開始
⏳ ・・・3秒後・・・
✅ 3000ms 経過
↓
🎉 すべて完了!
JavaScriptPromiseチェーンの仕組み(内部の動き)
Promise #1 ──.then()──▶ Promise #2 ──.then()──▶ Promise #3 ──.finally()
JavaScriptそれぞれの .then() は 新しい Promise を返している のがポイント。
つまり:
| thenの中の戻り値 | 次のPromiseの状態 |
|---|---|
| 通常の値 | fulfilled(成功) |
| Promiseを返す | そのPromiseの状態を引き継ぐ |
| 例外throw | rejected(失敗) |
よくある誤解ポイント
❌ 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