评论

[生存指南]面试题(6):深度掰扯事件循环,EventLoop详解

事件循环是浏览器的核心逻辑,搞懂后,可以解决很多奇葩问题

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环境)。

宏任务:

setTimeoutsetIntervalsetImmediate(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

这次就分享到这里,有任何疑问,欢迎留言~

最后一次编辑于  2023-07-31  
点赞 0
收藏
评论
登录 后发表内容