JavaScript の Promise について
しばらく触れていないとすぐ忘れてしまうので Promise についてのメモを残しておく。
基本的には JavaScript Primer を読み返すと理解が早い。
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) を返す。