- 首先,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天后你会看到全新的自己。