質問: ### 前提・実現したいこと 現在、JavaScriptの非同期処理を理解する必要があるため * コールバック * Promise * async/await について勉強していました。 しかし、Promiseの挙動について不可解な点があります。 ### 発生している問題 ``` function asyncFunc(val) { console.log("first"); return new Promise((resolve, reject) => { console.log("second"); resolve(val * 2); }) } asyncFunc(50) .then((val) => { console.log(val); }); console.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をスタックに入れて実行する。 という認識です。 そのため、上記のコードを実行すると 1. asyncFuncをスタックに積む 2. asyncFuncを解析すると、console.log("first")があるので実行する。 3. return new Promiseなので、WebAPIもしくはキューに中身を打ち込む。 (Promiseは、resolve, rejectがなされるまで内部状態が変わらないので、おそらくWebAPI・キューに積まれる) 4. console.log("here")を実行する。 5. スタックが空いたので、Promise内を実行し、まずsecondを出力する。 6. resolveを実行し、FulFilled状態になりthenメソッドが呼ばれる。 7. thenメソッド内のconsole.log(val)をスタックに積んで実行する。 という流れになると想定していました。 しかし、実際の実行順序は thenメソッドだけが後回しでそれ以外が先に実行されていました。 これはどういう実行順序、またはPromiseの仕組みなのでしょうか? よろしくお願いいたします。
回答: > > これはどういう実行順序、またはPromiseの仕組みなのでしょうか? > > > よくある勘違いですが、`new Promise`の引数に渡した関数は**同期的**に実行されます。 > > `executor` 関数(引用者注:`new Promise`の引数となる関数)は `resolve` 関数と `reject` 関数が渡されて `Promise` が実装されるとすぐに実行されます (`Promise` コンストラクターがオブジェクトを返すよりも前に `executor` は実行されます)。 ―MDNより > > >