- 首先,event loop是一個執行模型,在瀏覽器中和node.js中實現不一樣。
- 瀏覽器中,Eventloop是基於html5標準,而node.js是基於libux。
一:先看看瀏覽器端的
1.有宏任務與微任務
宏任務 macrotask
包括:
- script
- setTimeout
- setInterval
- setImmediate(這是node.js的方法)
- I/O
- UI rendering
微任務 microtask
包括:
- Promises
- Object.observe 監聽對象變化的方法
- MutationObserver 監聽Dom結構變化的方法
- postMessage window對象之間通訊的方法
圖解
ps:簡單來說,就是首先執行全局任務script,接着開始執行所有微任務,等待微任務執行完畢再進行下一個宏任務執行。
2.例子
例子1:
console.log("start");
setTimeout(()=>{
new Promise(resolve=>{
console.log("promise inner1");
resolve();
}).then(()=>{
console.log('promise then1')
})
},0);
new Promise(resolve=>{
console.log(('promise inner2'));
resolve();
}).then(()=>{
console.log('promise then2')
});
// 首先 start
// 然後執行微任務 打印出promise inner2 promise then2
// 再執行下一個宏任務 promise inner1 promise then1
例子2:
async function async1(){
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2(){
return Promise.resolve().then(_=>{
console.log('async2 promise');
});
}
console.log("strat");
setTimeout(function(){
console.log("setTimeout");
},0);
async1();
new Promise(function(resolve){
console.log("promise1");
resolve();
}).then(function(){
console.log('promise2');
})
//首先strat
// 然後async1 start promise1
// 這裏沒有等await去執行async2,因爲new Promise這段代碼是同步的
// await中async2 promise
// 再執行then中的promise2
// async1 end
// setTimeout
二:接着看看node.js端的
1.六個階段
ps:node.js的event loop是分階段的。其中我們着重關注timers、poll和check這三個階段。
2.node的Event Loop中poll階段
ps:
- 首先進入poll階段,看看是否爲空或者限制,否則執行callback。
- 接下來,如果setImmediate設置了callback,則等待callback加入poll重新來,同時觀察是否有到達時間的timer。
- 直到進入check階段。
舉個例子加深理解
3.例子
const fs = require('fs');
fs.readFile(__filename,_ => {
setTimeout(- => {
console.log("setTimeout");
},0);
setImmediate(- => {
console.logh('setImmediate');
})
});
執行順序如下:setImmediate setTimeout
ps:因爲check階段會先檢測是否設置了setImmediate,再等待callback加入poll,在這個等待過程中才會檢查timer
三:process.nextTick()
ps:是一個異步的node API,不屬於event loop階段
直接上例子
1.例子
const fs = require('fs');
fs.readFile(__filename,_ => {
setTimeout(- => {
console.log("setTimeout");
},0);
setImmediate(- => {
console.logh('setImmediate');
process..nextTick(_ => {
console.log("nextTick2")
})
});
process.nextTick(_ => {
console.log("nextTick1")
});
});
ps:
- nextTick會把整個event loop停下來,執行完後再繼續eventloop
- nextTick1 setImmediate nextTick2 setTimeout
好了,這就是小白對eventloop的簡單理解。做個筆記。
每天努力一點點,365天后你會看到全新的自己。