3秒でわかる
あとで成功か失敗が決まる値を包むJavaScriptのオブジェクト。通信やファイル読み込みの結果を await や .then() で受け取るための土台です。
30秒図解
もう少し詳しく
どういうものか
Promise は「いまはまだ結果が無いが、あとで成功か失敗のどちらかに必ず決まる」ことを表す JavaScript のオブジェクトです。状態は pending(処理中)、fulfilled(成功して値が確定)、rejected(失敗してエラーが確定)の 3 つで、一度確定した状態は二度と変わりません。fetch() や Node.js の fs/promises、setTimeout を包んだ関数など、時間のかかる処理はほぼすべて Promise を返します。
なぜ必要か
Promise が無かった頃、非同期処理の結果はコールバック関数で受け取っていました。処理を順番につなぐたびに関数が入れ子になり、5 段も重なると読めなくなります。しかもエラー処理を各階層で書く必要がありました。Promise は結果を「状態を持つ箱」にしたことで、後続処理を横に並べて書けるようにし、エラーを最後の .catch() 一箇所にまとめられるようにしました。
具体例
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function main() {
const res = await fetch("https://api.example.com/users/1");
if (!res.ok) throw new Error("取得に失敗しました");
const user = await res.json();
await wait(500);
console.log(user.name);
}
main().catch((err) => console.error(err.message));await は Promise が確定するまでその行で待ち、fulfilled なら中身の値を、rejected なら例外を投げます。
つまずきやすいところ
await を書き忘れると、値ではなく Promise { } がそのまま表示されるforEach のコールバックに await を書いても外側は待ってくれない。順番に待つなら for...of、並列でよいなら Promise.all() を使う.then() の中で return を忘れると次の .then() に値が渡らず undefined になるcatch の無い rejected Promise は Node.js だとプロセスが落ちる原因になる似た用語との違い
| 書き方 | 特徴 |
|---|---|
| コールバック | 引数に関数を渡す。入れ子が深くなる |
| Promise | 結果を包む値。.then() で連結できる |
| async / await | Promise を同期処理のような見た目で書く構文 |
async 関数は必ず Promise を返すので、両者は対立するものではなく同じ仕組みの別の書き口です。
覚え方
「引換券」と考えると腑に落ちます。券を受け取った時点で商品はまだ無く、あとで商品(値)かお詫び(エラー)のどちらかが必ず返ってきます。