はじめに
JavaScriptには2種類の非同期処理のキューが存在します。
それが、、Macrotasks
とMicrotasks
です。
それがどういったものかを見ていこうと思います!
Macrotasksとは
Macrotasksはタスクキューとも呼ばれており、1つずつタスクを実行します。
例えば、setTimeout
やsetInterval
などのコールバック関数が該当します。
※ジョブキューの後に実行される。
Microtasksとは
Microtasksはジョブキューと呼ばれており、順番が回ってきたら全てのタスクを実行します。
こちらはPromise
などが該当します。
※タスクキューのより先に実行される。
動きの解説
以下のコードを利用して実行順序がどうなっているかの解説を行います。
// 非同期処理かつMacrotaskなのでタスクキューに追加
setTimeout(function task1() {
console.log('task1');
});
// Promiseの即時関数を定義
new Promise(function promise(resolve) {
// この部分は同期的に処理されるので一番早くコンソール出力する
console.log('promise');
resolve();
}).then(function job1() {
// 非同期処理かつMicrotaskなのでジョブキューに追加
console.log('job1');
});
// グローバルコンテキストが終了したのでここが実行される
console.log('global end');
実行の流れ
①まず、setTimeout関数は非同期処理のためタスクキューに追加される。(ここでは実行されない)
②次に、Promiseの中身である関数では同期的に処理されるので、一番最初に処理されます。
③thenメソッドも非同期処理のため、タスクキューに追加されるため実行されません。
④ここで、最後の行のコードであるconsole.log('global end');
が実行されます。
⑤setTimeout関数はMacrotaskで、thenはMicroTaskなので、thenが先に実行されます。
⑥最後にキューに残っているsetTimeout関数の処理を実行して終了です。
ちなみに実行結果は以下の通りです。
"promise"
"global end"
"job1"
"task1"
終わりに
ややこしい部分ではありますが、ここを理解しておかないと実装時に意図しないエラーが発生することもあるので気をつけましょう!
参考
[【JavaScript】Macrotasks と Microtasks]
(https://hidekazu-blog.com/javascript-macrotasks-microtasks/)
[JavaScript初心者でもよくわかる!コードの非同期処理]
(https://tech.wwwave.jp/entry/javascript-async-execution)