generated at
Promise
JavaScript非同期処理をいい感じに書くためのやつ

Node.jsのコールバック地獄を滅ぼすことができる
promiseheaven.js
f(arg) .then(g) .then(h) .then(result => { console.log(result); }) .catch(err => { /* エラーハンドリング */ });

Promiseによる非同期関数は Promise インスタンスを同期的に返す
Promiseには3つの状態がある
結果が未確定の pending
処理に成功した fulfilled
処理に失敗した rejected
fulfilledとrejectedを合わせてsettledと呼ぶ
こんな感じ
pr.js
const divAfter = (ms, x, y) => { return new Promise((resolve, reject) => setTimeout(() => { try { resolve(x / y); } catch (e) { reject(e); } }, ms) ); }; divAfter(1000, 10n, 10n).then((value) => { console.log(value); }); divAfter(1000, 10n, 10n).catch((err) => { console.error(`err: ${err}`), process.exit(1); });

即座にsettledなPromiseインスタンスを生成する方法もある
Promise.resolve() Promise.reject()

非同期処理の逐次実行はインスタンスメソッドで行う
promise.then()
コールバック onFulfilled onRejected を登録する
promise.then(value => {成功時の処理}, err => {失敗時の処理})
Promiseがfulfilledになったとき onFulfilled が呼ばれる
このとき then の返り値は onFulfilled で返した値で解決される新しいPromiseインスタンス
Promise.resolve(1).then(value => value + 1) の返り値は 2 に解決されるPromise
Promise.resolve(1).then(value => value + 1, err => \ ${err.message}\ ) も同じ
Promiseがrejectedになったとき onRejected が呼ばれる
このとき then の返り値は onRejected の返り値で解決されたPromiseインスタンスになる
Promise.reject(new Error("error!")).then(value => value + 1, err => \ ${err.message}\ ) の返り値は "error!" に解決されるPromsie
onRejected を省略した場合エラーがそのまま渡る
Promise.reject(new Error("error!")).then(value => value + 1) は unhandled rejection になる
onFulfilled onRejected でエラーがthrowされると then の返り値はそれでrejectされる
Promise.resolve(1).then(_ => throw new Error("hoge")) はErrorインスタンスでreject
Promise.reject(1).then(_ => _, throw new Error("hoge")) もErrorインスタンスでreject
onFulfilled onRejected でPromiseを返す、つまりPromiseのネストを試みると潰される
Promise.resolve(1).then(value => Promise.resolve(value + 1)) 1 に解決されるPromise
(t: T) => Promise<R> みたいな関数 (非同期関数) をthenに渡して処理をつなげられる
promise.catch(onRejected)
promise.then(undefined, onRejected) と等価
promise.then(f).then(g).then(h).catch(errorHandling) とすればすべてのエラーをerrorHandlingで捕捉できる
promsie.finally(onFinally)
Promiseがsettledになったときコールバックを実行する
やはり返り値は新しいPromiseインスタンス
コールバックからPromiseを返した場合、finallyの返り値のPromiseはそれを待つ
finallyの返り値のPromiseが解決される値はfinallyを呼び出したインスタンスと同じになる
生の値だろうとPromiseだろうと、コールバックの返り値は影響しない
finallyのコールバックがエラーを発生した場合はfinallyの返り値のPromiseがそれで拒否される
promise.finally(() => { throw new Error(); }) promise.finally(() => Promise.reject(new Error()))
then catch fanally のコールバックはかならず非同期的に実行される

非同期処理の並行実行は globalThis.Promise に生えた関数で行う
イテラブルを引数にとりPromiseを返す
Promise.all
すべてのPromiseがfulfilledになったときそれらを配列で持ったfulfilledなPromiseになる
1つでもrejectedになると他を待たず即座にその値でrejectする
Promise.race
一番早くsettledになったPromiseをそのまま返す
空のイテラブルを渡すと永遠にpending
非同期処理とt秒後に拒否されるPromiseを並べれば、非同期処理がt秒までに終わらかなった場合rejectされるタイムアウト処理が作れる
Promise.allSettled
すべてのPromiseがsettledになったらそれらの結果を配列に詰めて返す
結果はTypeScriptでいうと { status: "fulfilled", value: T } | { status: "rejected", reason: unknown }
Promise.any
一番早くfulfilledになったPromiseをそのまま返す
全部rejectedだったらそれを AggregateError インスタンスに詰めて返す