nodeのPromiseを触る機会があり全くできずに愕然としました。脳内インタプリターで出力できるように例題をやりつつ訓練しようと思います。
理解まとめ
- promise
- promsieは最終的には、処理の成功か失敗かの状態が保持されるオブジェクト
- promiseオブジェクトを作成し、非同期処理を登録する。
- const promiseA = new Promise((resolve,reject) => {…});
- 非同期処理内での失敗や成功かの状態をresolveやrejectを利用して記述する。
- resolve/rejectがなかった場合、thenメソッド実行時に登録されたcallback関数は呼ばれない
- resolve/rejectは登録された非同期処理の処理を中断しない
- 複数のresolve/rejectがある場合、最初に呼ばれたものが優先される。
- then
- thenはpromiseクラスのメソッド
- promiseA.then(successCB,failureCB)のように引数にcallback関数を登録し、promiseAの実行後にsuccessCBまたはfailureCBを呼び出す。
- promiseAの実行が成功した場合(resolveが呼ばれた場合):successCB
- promiseAの実行が失敗した場合(rejectが呼ばれた場合):successCB
- thenメソッドの戻り値は、登録されたcallback関数内でreturnされた値をresolveでくるんだPromiseオブジェクトを作成して返す。
- returnされる値がない場合、空のresolveが返される
- thenメソッドに登録されたcallback関数内でのreturnに関して以下の3つは同等
- return 100
- return new Promise((resolve,reject) => { resolve(100) });
- return Promise.resolve(100);
- new Promiseしてresolveするシンタックスシュガー
- Promise.reject(-1)なども同様に利用可
- catch(cb)はthen(null,cb)のシンタックスシュガー
- 参考
例題1. resolve
した場合
function testPromise() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("testPromise"); resolve(); }, 2000); }); } console.log("start"); testPromise().then(() => { console.log("then"); }).catch(() => { console.log("catch"); }) console.log("end");
結果1
start end <2秒待ち> testPromise then
例題2. reject
した場合
function testPromise() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("testPromise"); reject(); }, 2000); }); } console.log("start"); testPromise().then(() => { console.log("then"); }).catch(() => { console.log("catch"); }) console.log("end");
結果2
start end <2秒待ち> testPromise catch
例題3. new Promise(func)
のfunc内でresolve/rejectしなかった場合
function testPromise() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("testPromise"); }, 2000); }); } console.log("start"); testPromise().then(() => { console.log("then"); }).catch(() => { console.log("catch"); }) console.log("end");
結果3
start end <2秒待ち> testPromise
備考:resolve/rejectが呼ばれなかった場合、thenメソッドに登録されたcallback関数は呼ばれない
例題4. new Promise(func)
のfunc内でresolve
した後に処理を記述した場合
function testPromise() { return new Promise((resolve, reject) => { setTimeout(() => { resolve("resolve"); console.log("testPromise after resolve"); }, 2000); }); } console.log("start"); testPromise().then((result) => { console.log(result); console.log("then"); }).catch((err) => { console.log(err); console.log("catch"); }) console.log("end");
結果4
start end <2秒待ち> testPromise after resolve resolve then
備考:resolve()/reject()は処理を中断しない
例題5. new Promise(func)
内にresolve,reject
がある場合
function testPromise() { return new Promise((resolve, reject) => { setTimeout(() => { reject("reject"); resolve("resolve"); console.log("testPromise"); }, 2000); }); } console.log("start"); testPromise().then((result) => { console.log(result); console.log("then"); }).catch((err) => { console.log(err); console.log("catch"); }) console.log("end");
結果5
start end <2秒待ち> testPromise reject catch
備考:Promiseの処理内で複数のresolve/rejectがある場合、最初に呼ばれたものが優先される。
例題6. 以下のコードをcatchを使わずに記述するには?
testPromise().then((result) => { console.log("then"); }).catch((err) => { console.log("catch"); })
結果6
//thenメソッドの第二引数にエラー時のコールバック関数を登録 testPromise().then((result) => { console.log("then"); }, (err) => { console.log("catch"); }) //またはチェーンでつなぎ、thenメソッドの第一引数をnullにする testPromise().then((result) => { console.log("then"); }).then(null, (err) => { console.log("catch"); })
備考: catch(failureCallback)
は then(null, failureCallback)
を短く記述したもの。
例題7. thenメソッドの中のreturn
function testPromise() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("testPromise"); resolve("resolve!"); }, 2000); }).then((result) => { console.log(result); return 100; }); } console.log("start"); testPromise().then((result) => { console.log(result); console.log("then"); }, (err) => { console.log(err); console.log("catch"); }) console.log("end");
結果7
start end <2秒待ち> testPromise resolve! 100 then
備考:thenメソッド内のreturnはresolveでラップされる
コメント