浏览器事件队列

1. 为什么需要事件队列

js是单线程语言,一次性只能执行一个任务。而有些任务比较耗时,如网络请求、定时器等,会阻塞后续任务进行。因此,需要一种异步解决方案,尽可能使应用可以流畅运行--事件队列,或者说消息队列。

2. 什么是事件队列

事件队列,就是浏览器处理多任务的异步解决方案。

它会把任务划分到各个队列之中,依次执行。

它可以帮助我们优化性能,将耗时的任务放在队列中,在空闲的时候执行,以免阻塞主线程。

3. 事件队列的处理方式

以Chrome浏览器为例,每个标签页都是一个独立的进程。而该进程在处理任务时,会有一个主线程。主线程会处理包括渲染页面,事件交互等诸多任务。为了防止事件阻塞,浏览器会把各个任务分配到不同的事件队列中,而不同的事件队列,有不同优先级。

  • 微任务队列:主线程完成后会立即执行的任务队列,通常是异步任务的回调, 如Promise和MutationObserver 的回调。浏览器会将回调函数包装成任务,插入微队列中。优先级高。
  • 宏任务队列:存储需要异步执行的任务,如定时器、用户交互、I/O操作等。

任务队列遵从先进先出的原则。即任务按照被添加到队列中的顺序来进行执行。

那么,事件队列是怎么运作的呢?

function Fn () {
    console.log(1)
}

setTimeout(() => {
    console.log(2)
},0)

console.log(3)

new Promise((resolve, reject) => resolve()).then(() => Fn())

以上述代码举例,浏览器拿到js开始执行,主线程开始分析当前任务并划分队列。

1. 主线程执行同步任务

2. 将产生的新任务划分到不同队列

3. 继续执行同步任务,直至主线程中同步任务全部执行,等待下一个同步任务到来

4. 开始执行微任务

5. 渲染与更新

6. 重复步骤3-5,直至队列清空

7. 开始执行宏任务

8. 重复以上步骤,直至所有任务清空,进入等待状态

以上步骤会一直循环进行,也就是事件循环 

因此,上述代码输出应为 

3 1 2

到这里,事件队列处理机制就很清晰了,所以我们再加一丶丶难度。

function Fn (x) {
    console.log(x)
}

new Promise((resolve, reject) => resolve()).then(() => {
    console.log(1)
    new Promise((resolve, reject) => resolve()).then(() => Fn(2))
})

setTimeout(() => {
    console.log(3)
    new Promise((resolve, reject) => resolve()).then(() => Fn(4))
}, 0)

console.log(5)

new Promise((resolve, reject) => resolve()).then(() => {
    console.log(6)
    setTimeout(() => Fn(7), 0)
})

所以,这里输出的结果会是多少呢? 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值