一、在了解event loop前,我们首先要知道一些基础知识
宏任务:script全部代码、setTimeout、setInterval、setImmediate、I/O、UI Rendering。 微任务:Process.nextTick(Node 独有)、Promise 等。
event loop大体由三个部分组成:调用栈(call stack)、消息队列(Message Queue)、微任务队列(Microtask Queue)。这三个部分在event loop中非常重要。
在ES6规范中,microtask称为jobs,macrotask称为task microtask(微任务):process.nextTick、Promise、MutationObserver等 macrotask(宏任务) :setTimeout、setInterval、setlmmediate、script(整体代码)、I/O操作等。
二、event loop(事件循环)的运行机制
下面通过一些例子举例说明什么是event loop
注意:浏览器event loop和node中的event loop不同
1.只有宏任务时
function fn1(){
console.log(5)
setTimeout(function(){
console.log(4)
},0)
}
function fn2(){
console.log(6)
fn1()
console.log(7)
}
fn2();
调用栈 消息队列
| | -------------------------
| |
| | -------------------------
------------------------
//输出 6 5 7 4
总结:首先将按顺序执行,遇到函数压入栈,遇到宏任务压入消息队列,栈清空后执行消息队列。
2.即有宏任务,又有微任务
let p = new Promise(function(resolve){
console.log(3)
resolve()
})
function fn1(){
console.log(5)
setTimeout(function(){
console.log(4)
},0)
}
function fn2(){
p.then(funtion(){
console.log(1)
})
console.log(6)
fn1()
console.log(7)
}
fn2();
调用栈 消息队列
| | -------------------------
| | consolo.log(4)
| | -------------------------
------------------------
微任务队列
-------------------------
consolo.log(1)
-------------------------
//输出 3 6 5 7
总结:遇到微任务会加入微任务队列,当调用栈清空时,如果消息队列和微任务队列都有内容,先执行微任务队列,再执行消息队列。