久々にjavascriptで非同期処理書いててちょっと混乱したので基本的な動作を整理。
非同期処理を逐次処理する方法を書いていきます。
まず1秒後に文字列を返すPromiseを用意します。
1 2 3 4 5 6 7 |
const pro = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve("promise!"); }, 1000); }); }; |
これを通常のコードで使ってみるとこうなります。
1 2 3 4 |
const aa1 = () => { let v = pro(); console.log(v); // Promise { <pending> } }; |
このとき値はPromiseそのものになっています。
then()
でコールバックするかasync/await
で非同期待機処理を簡潔に書けます。
1 2 3 4 5 6 7 8 9 10 |
const aa1_1 = () => { let v = pro(); v.then(v => { console.log(v); // "promise!" }); }; const aa1_2 = async () => { let v = await pro(); console.log(v); // "promise!" }; |
async/await
で返値がある場合にはどうなるか。
1 2 3 4 |
const aa2 = async () => { let v = await pro(); return v; }; |
aa2()
は非同期関数になるので、他から呼び出すとこうなります。
1 2 3 4 |
const aa2_1 = () => { let v = aa2(); console.log(v); // Promise { <pending> } }; |
Promiseと同じように非同期後の処理を書くことが出来ます。
1 2 3 4 5 6 7 8 9 10 |
const aa2_2 = async () => { let v = await aa2(); console.log(v); // "promise!" }; const aa2_3 = () => { let v = aa2(); v.then(v => { console.log(v); // "promise!" }); }; |
コールバック関数を渡すという方法もあります。
1 2 3 4 5 6 7 8 9 |
const aacb = async cb => { let v = await pro(); cb(v); }; const aa3 = () => { aacb(v => { console.log(`callback with ${v}`); // callback with promise! }); }; |
まあthen()
でコールバック出来るのにこうする必要はないと思います。
async/await
は複数の非同期処理を順番に処理する場合に効果的です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
const aa4_1 = () => { pro().then(v => { console.log(v); pro().then(v => { console.log(v); pro().then(v => { console.log(v); console.log("end"); }); }); }); }; const aa4_2 = async () => { console.log(await pro()); console.log(await pro()); console.log(await pro()); console.log("end"); }; |
書きやすいし分かりやすい。
ただ、非同期処理の逐次処理を簡単に書けるのでこれ(aa4_2
)自体が非同期処理であるということを忘れないようにしないといけません。
また今回は逐次処理だけですが、何でもasync/awaitを使えばいいというわけでもないというのを1年前の自分に教えてもらいました。
多分この時の方が理解度高かったんだろうなー。