TL;DR
非同期処理が最終的に完了したか失敗したかと、その結果の値を表す JavaScript のオブジェクト。作った時点ではまだ分からない値の代理として振る舞う。
なぜ必要か
コールバックで非同期処理を書くと、ネストが深くなり、実行順序がコードの順序と逆になるなど、可読性が低かった。Effective TypeScript 項目27 では、組み合わせやすさと型の流れを考えて、非同期処理はコールバックではなく Promise で書くよう勧めている。
仕組み
Promise は次の 3 つの状態のどれかをとる。
- pending(待機): 初期状態。履行も拒否もされていない
- fulfilled(履行): 処理が成功した
- rejected(拒否): 処理が失敗した
履行か拒否のどちらかになり、pending でなくなった状態を settled(決定)と呼ぶ。
then()、catch()、finally() で、Promise が決定した後の処理を登録する。これらは新しい Promise を返すので、つなげて書ける。ハンドラが値を返せば新しい Promise はその値で履行され、エラーを投げればそのエラーで拒否される。拒否はどこかで処理されるまでチェーンを伝わる。
複数の Promise をまとめて扱う静的メソッドもある。
Promise.all(): すべてが履行されたら履行し、どれかが拒否されたら拒否するPromise.allSettled(): すべてが決定したら履行するPromise.any(): どれかが履行されたら履行し、すべてが拒否されたら拒否するPromise.race(): どれかが決定したら、同じ結果で決定する
例
myPromise
.then((value) => `${value} and bar`)
.then((value) => `${value} and bar again`)
.catch((err) => {
console.error(err)
})