async/awaitはPromiseの糖衣構文です。
結論から言えば質問文のコードは動かなくて当然なので、
まずはぐっと我慢してPromiseという非同期処理の仕組みを勉強してください。
Promiseの仕組みさえ理解していれば、
こんな感じで解決することが出来るようになります。
JavaScript
1async function test() {
2 const log2 = () => new Promise(resolve =>
3 setTimeout(() => resolve(2), 1000)
4 );
5 console.log(1);
6 console.log(await log2());
7 console.log(3);
8}
9test();
10// 1
11// 2 <- 1秒程待ってから出力
12// 3 <- 2の後に出力
とはいえ、無策でPromise - MDNへ突撃しても泣かされて帰ってくるのがオチなので、
多少アドバイスしておきます。
まず元祖非同期処理に関して
JavaScriptはシングルスレッドなので並列実行が出来ません。
なのでイベント駆動という概念が存在しています。
イベント置き場に、「イベント発火条件」と「実行して欲しい関数」とセットで登録し、
処理自体は速攻で終わります。
その後、イベントループという巡回が始まり、イベント発火条件を満たした関数を1つずつ取り出して順次実行していくという流れになっています。
(他にもイベントループより優先して実行する割り込み的なルールも存在しますが割愛)
setTimeout(fn, 1000)
がその代表的な例です。
「1000ミリ秒経過したら、併設の関数を実行しなさい」
明確ですね。
実際にはイベントループでの巡回を経てから実行に移す為、
1000ミリ秒きっかりで実行するのではなく、数ミリ秒の誤差が生じます。
これによりシングルスレッドでありながら、遅延や並列処理を手にする事に成功しました。
しかし、関数の中にやりたいことを全部書けとは中々クレイジーですね。
関数を無限に挟み込む事になってしまいます。
この関数定義で無限にコードがネストしていく事を「コールバック地獄」と呼びます。
Promiseの説明
Promiseとはコールバック地獄を解決する目的で作られた、
オブジェクト指向のデザインパターンのようなものです。
Promise式の非同期処理の関数を実行した場合、
即刻Promiseオブジェクトのインスタンスが帰ってきます。
このPromiseオブジェクトは今何かしらの処理を実行しているから「待っていてね」を示すPending状態になっており、
実行が完了して状態が正常終了(fulfilled)になった場合完了を表します。
Promiseインスタンスには.then(fn)
メソッドが用意されており、
完了次第実行して欲しい内容を関数で包んで.then(fn)
で登録しておけば、
Promiseの状態が正常終了(fulfilled)になった瞬間に関数を実行してくれます。
なーんだ非同期のコールバック地獄と同じじゃん、何が嬉しいの?
それは。then(fn)
の中身の関数がPromiseを返すようにしておけば、
.then(fn).then(fn)
とメソッドチェーンでコードを記述出来るということです。
これにより、やってることは実質変わらないけど、
コールバック地獄の無限ネストを1段階のネストで抑え込む事が可能になりました。
質問文をPromiseでやるとこんな感じのコードになります。
JavaScript
1function test() {
2 console.log(1);
3 new Promise(resolve =>
4 setTimeout(() => resolve(2), 1000)
5 ).then(value => {
6 console.log(value);
7 console.log(3);
8 })
9}
10test();
11// 1
12// 2 <- 1秒後に出力
13// 3 <- 2の直後に出力
async/await構文とのつながり
先程async/awaitはPromiseの糖衣構文と記載しました。
async構文で作った関数は、絶対Promiseインスタンス返すマンみたいな挙動で、
return value
をPromiseのコンストラクタの引数resolve
関数を実行するのと同じ挙動をします。
それとは別にawait構文がasync関数の中身で使用可能になります。
await構文は右辺のPromise完了を一生待ちます。
実行が完了したと想定して後続のコードを全て.then(fn)
で包んだ挙動として宣言します。
これにより一見非同期のコードを動的にプログラミング出来ているといった形になります。
詳しい内容はMDNのサイトを見てください。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/25 04:00