JavaScript の Promise について

しばらく触れていないとすぐ忘れてしまうので Promise についてのメモを残しておく。

基本的には JavaScript Primer を読み返すと理解が早い。

Promise の状態

Promiseの状態
Promiseの状態

new Promise(executer) すると Pending 状態の Promise インスタンスが生成される。 executer は同期的に(つまり、new Promise を呼び出した瞬間に)実行される。 executer はお馴染みの 以下のような関数。

(resolve, reject) => {
    // 処理が成功したときはresolveを呼ぶ
    // 処理が失敗したときはrejectを呼ぶ
}

この関数内で同期的な関数しか呼んでいなければ、すぐさま Fulfilled or Rejected の状態に遷移するし、 非同期の関数を呼んでいれば非同期処理の結果で Fulfilled or Rejected の状態に遷移する。

Promise.resolve と Promise.reject

Promise.resolve は Fulfilled 状態の Promise インスタンスを返す。 実態は new Promiseの糖衣構文。

// const fulfilledPromise = Promise.resolve(); と同じ意味
const fulfilledPromise = new Promise((resolve) => {
    resolve();
});

Promise.reject も Rejected 状態の Promise インスタンスを返すだけで同様。

例外

new Promise(executer) のexecuter 内で発生した例外は、 reject と同じ扱いになる。 executer 内の

reject(new Error(message));

throw new Error(message);

はほぼ同じ。

then と catch

Promise インスタンスに対して then(onFulfilled, onRejected) を呼び出すと、Promise インスタンスの状態が Fulfilled or Rejected となった時に onFulfilled or onRejected が呼び出される。 catch は then(undefined, onRejected) と同じ処理を catch(onRejected) として書ける。

thenの返り値

then は Promise インスタンスを返す。 これによって、Promiseチェーンが実現されている。

then(onFulfilled, onRejected) において、

  • onFulfilled or onRejected が Promiseインスタンスを返す場合
    → この場合特別扱いされ、onFulfilled or onRejected が返した Promise インスタンスをthen もそのまま返す。
  • onFulfilled or onRejected が Promiseインスタンス以外の値を返す場合
    → onFulfilled or onRejected が返したvalueに対して then は Promise.resolve(value)を返す。
  • onFulfilled or onRejected 内で例外が発生した場合
    → 発生したerror に対して then は Promise.reject(error) を返す。