EventLoop 宏任務和微任務
js中用來存儲執行回調函數的隊列包括2個不同的特定的隊列,即宏隊列和微隊列
宏任務包括定時器、ajax異步回調、事件回調
微任務包括promise,mutation
需要明確的是,所有函數,不論宏任務隊列微任務隊列或者是同步執行的函數,最終都是要放到在棧里面調用執行的
執行順序:
- js引擎首先必須先執行所有的初始化同步任務代碼
- 每次准備去除第一個宏任務前,都要將所有的微任務一個一個取出來執行
- 對於then的鏈式調用,只有當前then的上一個then執行完畢之后,當前then才會被加入微任務隊列(而不是立即執行,僅僅只是加入隊列)
棧里面的同步執行函數,然后是微隊列,然后是宏隊列
假如隊列里有多個任務,那么隊列里的任務按加入的順序依次執行

測試用例
0
setTimeout(() => {
console.log('宏任務 settimeout')
}, 0)
Promise.resolve(1).then(
value => {
console.log('微任務 promise')
}
)
let a = function(){
console.log('synchronize fn')
}
a()
// 打印順序
/*
synchronize fn
微隊列 promise
宏隊列 settimeout
*/
1
setTimeout(()=>{
console.log(1)
})
Promise.resolve(2).then(
value => console.log(value)
)
Promise.resolve(3).then(
value => console.log(value)
)
console.log(4)
/*
打印順序
4
2
3
1
*/
2
setTimeout(()=>{
console.log(1)
},0)
new Promise((resolve)=>{
//執行器函數,同步的,首先打印
console.log(2)
resolve()
})
.then(
()=>{
console.log(3)
}
)
.then(()=>{
console.log(4)
})
console.log(5)
/*
打印順序
2
5
3
4
1
*/
3
/*
1 7 2 3 8 4 6 5 0
微隊列:[4 6 5]
宏隊列:[0]
*/
setTimeout(() => {
console.log("O")
}, 0)
new Promise((resolve, reject) => {
console.log("1")
resolve()
})
.then(() => {
//微任務1
console.log("2")
new Promise((resolve, reject) => {
console.log("3")
resolve()
}).then(() => {
//微任務3,此時3在隊列里,3沒有執行,5不會被放入隊列,3執行了5才會放入隊列
console.log("4")
}).then(() => {
//微任務5
console.log("5")
})
}).then(() => {
//微任務4
console.log("6")
})
new Promise((resolve,reject)=>{
console.log('7')
resolve()
}).then(()=>{
//微任務2
console.log('8')
})
4
/*
1 4 2 3 5
*/
document.addEventListener("chilema", chileMaHandler);
console.log(1);
function fn1() {
fn2();
console.log(2);
}
function fn2() {
console.log(3);
}
console.log(4);
function chileMaHandler() {
fn1();
console.log(5);
}
document.dispatchEvent(new Event("chilema"));
/*
1 4 2 3 5
6 12 16 15 7 8 9 10 11 13 14
微隊列:[]
宏隊列:[14]
*/
new Promise(function (resolve, reject) {
console.log(6);
setTimeout(function () {
console.log(7);
resolve();
}, 0);
}).then(function () {
console.log(8);
}).then(function () {
console.log(9);
})
setTimeout(function () {
console.log(10);
Promise.resolve().then(function () {
console.log(11);
})
}, 0);
new Promise(function (resolve, reject) {
console.log(12);
setTimeout(function () {
console.log(13);
}, 0);
resolve();
}).then(function () {
setTimeout(function () {
console.log(14);
});
Promise.resolve().then(function () {
console.log(15);
});
console.log(16);
})
