Macrotask,Microtaskとは
非同期処理のキューをさらに2分して、タスク処理の順番をさらに制御しておく
内訳
1.マクロタスク
*setTimeout
*setInterval
*MutationObserver
2.マイクロタスク
*Promise
Macrotask,Microtaskで覚えておくべきこと
1. マイクロタスクはマクロタスクよりも優先される
2. マイクロタスクはすべてのジョブを終了してからマクロタスクにうつる
3. マクロタスクは1つのジョブがおわったときに再びマイクロタスクに移る
例
例題
new Promise(function promise(resolve) {
console.log('promise');
setTimeout(function task1() {
console.log('task1');
resolve();
});
setTimeout(function task1() {
console.log('task2');
const p = Promise.resolve();
p.then(function job4() {
console.log('job4')
})
queueMicrotask(function job4() {
console.log('job4')
})
});
}).then(function job1() {
console.log('job1');
}).then(function job2() {
console.log('job2');
}).then(function job3() {
console.log('job3');
})
console.log('global end');
読解
例題
new Promise(function promise(resolve) {
// 1.new以下は通常通り実行されます。1番目
console.log('promise');
// 2.set以下{}はマクロタスクなので一旦無視。
setTimeout(function task1() {
// 5.ひとまずグローバルスコープが終わったので、3番目
console.log('task1');
// 6.resolveを実行する。4番目
resolve();
});
// 7.setTimeout()はマクロタスクなので一旦保留
setTimeout(function task1() {
// 9.ここでやっとtask2を呼ぶ 7番目
console.log('task2');
// 10.resolvetask2を呼ぶ 8番目
const p = Promise.resolve();
p.then(function job4() {
console.log('job4')
})
// 11.ラスト 9番目
queueMicrotask(function job4() {
console.log('job4')
})
});
// 3..thenはresolve()が上記のset内にしかないので一旦無視
// 8..resolveで呼ばれたので4番目~6番目
}).then(function job1() {
console.log('job1');
}).then(function job2() {
console.log('job2');
}).then(function job3() {
console.log('job3');
})
// 8.ここまで
// 4.グローバルコンテキストなので、上記のやつらを飛ばし続けた結果 2番目に
console.log('global end');
少し変えてみた
1.new{}の中でdresolveを一番前にする
new Promise(function promise(resolve) {
// 1.resolveを一番前
resolve();
resolve();
console.log('promise');
setTimeout(function task1() {
console.log('task1');
//ケツに回される
setTimeout(function task1a() {
console.log('task1a');
});
});
2.setTimeoutの間
2.setTimeoutの間
new Promise(function promise(resolve) {
console.log('promise');
setTimeout(function task1() {
console.log('task1');
setTimeout(function task1a() {
console.log('task1a');
});
});
// 2.setTimeoutの間
resolve();
resolve();
setTimeout(function task1() {
3.setTimeout()を入れ子にする
3.setTimeout()を入れ子にする
new Promise(function promise(resolve) {
console.log('promise');
setTimeout(function task1() {
console.log('task1');
// 3.入れ子
setTimeout(function task1a() {
console.log('task1a');
});
});
resolve();
resolve();
setTimeout(function task1() {
結果
*1.new{}の中でresolveを一番前にする
*2.setTimeoutとsetTimeoutの間にresolve()を入れる
*3.setTimeout()を入れ子にする
1-3同じ挙動で
*1.resolve()をconsole.log('promise');の前で呼んでみたが
console.log('promise');は同期処理なので。こちらが優先される
*2.setTimeoutはマクロタスクのため、連チャンで呼ばれない
*3.入れ子にしたSettimeoutは一番最後に呼ばれた