前提・実現したいこと
現在、JavaScriptの非同期処理を理解する必要があるため
- コールバック
- Promise
- async/await
について勉強していました。
しかし、Promiseの挙動について不可解な点があります。
発生している問題
javascript
1function asyncFunc(val) { 2 console.log("first"); 3 return new Promise((resolve, reject) => { 4 console.log("second"); 5 resolve(val * 2); 6 }) 7} 8 9 10asyncFunc(50) 11 .then((val) => { 12 console.log(val); 13 }); 14 15console.log('here');
以上のコードをブラウザで実行したときに、実行順序が
first second here 100
のようになります。
個人的には、
first here second 100
の順番で出力されると考えていました。
上記のような順番であると考える理由
JavaScriptの勉強内で
ChromeのようなWebブラウザは
v8(ブラウザ内のjs実行エンジン)
- シングルスレッド
- スタック(関数・処理を積んでいく)
Web API
- DOM
- Timer
- setTimeout
キュー
- もしv8のスタックが空なら、非同期処理が終わった部分をスタックに戻す
という3構成であると考えていました。
例えば、setTimeout(f)を実行すると
まずスタックに入り
その後setTimeoutなので、Web APIだ! とブラウザが代わりに実行して(タイマーを測って)
そして、タイマーの時間になったら、キューに移し、スタックが空いている瞬間があったらfをスタックに入れて実行する。
という認識です。
そのため、上記のコードを実行すると
- asyncFuncをスタックに積む
- asyncFuncを解析すると、console.log("first")があるので実行する。
- return new Promiseなので、WebAPIもしくはキューに中身を打ち込む。
(Promiseは、resolve, rejectがなされるまで内部状態が変わらないので、おそらくWebAPI・キューに積まれる)
- console.log("here")を実行する。
- スタックが空いたので、Promise内を実行し、まずsecondを出力する。
- resolveを実行し、FulFilled状態になりthenメソッドが呼ばれる。
- thenメソッド内のconsole.log(val)をスタックに積んで実行する。
という流れになると想定していました。
しかし、実際の実行順序は
thenメソッドだけが後回しでそれ以外が先に実行されていました。
これはどういう実行順序、またはPromiseの仕組みなのでしょうか?
よろしくお願いいたします。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/11 07:57
2019/09/11 08:06 編集
2019/09/11 08:35