1、什么是 EventLoop
事件循环(Event Loop)是一种处理异步操作的机制,常用于编写异步JavaScript代码。下面是一个简要的事件循环执行顺序的介绍:
-
执行同步代码:
当事件循环开始时,首先会执行当前执行上下文中的同步代码,这些代码是按照顺序执行的。 -
处理微任务(Microtasks):
在执行完同步代码后,事件循环会检查当前微任务队列是否有任务需要执行。微任务包括Promise回调、MutationObserver和process.nextTick等。如果有微任务,它们会依次被执行,直到微任务队列为空。 -
处理宏任务(Macrotasks):
在执行完所有的微任务后,事件循环会检查宏任务队列是否有任务需要执行。宏任务包括setTimeout、setInterval、I/O操作和UI渲染等。如果有宏任务,它们会依次被执行,一直执行到宏任务队列为空或者达到某个限制(例如某个定时器达到设定的时间)。 -
执行渲染:
如果宏任务执行过程中有对UI进行了修改(例如修改了DOM),则浏览器会执行重新渲染。 -
再次处理微任务:
在重新渲染后,事件循环会再次检查微任务队列是否有任务需要执行,并且会一直处理微任务队列直到它为空。(重点) -
重复执行事件循环:
上述步骤会不断重复,构成了事件循环的执行顺序。
2、执行顺序
同步任务 -> 微任务 -> (事件委托) -> 宏任务
注意:在浏览器(chrome)环境中,事件委托通常比宏任务更快被执行。
事件委托是一种优化技术,通过将事件处理程序添加到父元素而不是每个子元素上来处理事件。当事件在子元素上触发时,事件会冒泡到父元素,并在父元素上触发事件处理程序。这样做的好处是减少了事件处理程序的数量,从而减少了内存消耗,提高了性能。
3、异步任务
异步任务分为 宏任务和微任务;
微任务:
Promise.then()
,.then中的逻辑是微任务;process.nextTick
(node环境)。
宏任务:
setTimeout
、setInterval
、setImmediate
(node环境)、xhr
(发送网络请求),callback
。
4、案例实战(巩固知识点)
function app() {
Promise.resolve().then(() => {
console.log(1)
setTimeout(() => {
console.log(2)
})
Promise.resolve().then(() => {
console.log(3)
setTimeout(() => {
console.log(4)
})
})
})
console.log(5)
setTimeout(() => {
console.log(6)
Promise.resolve().then(() => {
console.log(7)
})
})
}
app();
// 思考2分钟后请写出答案
// 思考ing...
// 思考ing...
// 思考ing...
// 思考ing...
答案: 5136724
这里的难点在于3和6,以及7和2的顺序。
- 3和6顺序的问题在3是微任务中的微任务,实际还在任务队列里,所以3比6优先,6一定是在执行完所有微任务后
- 7和2的顺序在于,虽然7是宏任务6中的微任务,但当3执行完后,6就开始执行了,并将7放在微任务中了,而2虽然也是宏任务,但在6宏任务后,所以6执行完后一定是先执行新的微任务7,然后再轮到宏任务2
这次就分享到这里,有任何疑问,欢迎留言~