简述浏览器端js的事件循环(eventloop)

js语言是单线程的,同一时刻只能做一件事情,为了协调事件、用户交互、UI渲染和网络请求等行为,防止主线程进入阻塞,eventloop的方案应运而生。eventloop包含两类:一类是基于 Browsing Context,一类是基于Worker,二者是独立的。这里主要说一下基于浏览器端的事件循环。

每个事件循环中都包含一个 currently running task(task或者null),一个microtask queue(微任务队列,初始值为空),一个performing a microtask checkpoint(执行微任务检查点布尔值,初始值是false,用于阻止微任务的可重入调用)。

任务队列(task queue)

事件循环是使用任务队列的机制来实现的。一个eventloop中,可以有一个或多个任务队列(task queue),一个任务队列是一系列有序任务(task)的集合(set)。

注意,microtask queue 不是 task queue

任务(task)

通常,一个任务由以下几个部分组成:

  • Steps:任务要完成的工作的一系列步骤。
  • A Source:任务源之一,对相关任务进行分组和序列化。
  • A Document:与任务关联的文档,对于不在窗口事件循环(window event loop)中的任务,为null。
  • A script evaluation environment settings object set:一组环境设置对象,用于跟踪任务期间的脚本计算。

如果任务的文档为null或完全活动(fully active),则该任务是可运行的。
每个任务的任务源(source)都来自特定的任务源。对于每个事件循环,每个任务源都必须与特定的任务队列相关联。

任务源(task source)

任务源用于分离逻辑上不同的任务类型,源自同一个任务源的任务必须放在同一个任务队列中。

任务源包括以下几种:

  • The DOM manipulation task source,// DOM操作任务源
  • The user interaction task source,// 用户交互任务源
  • The networking task source,// 网络相关任务源
  • The history traversal task source,// 历史记录任务源
  • microtask task source // 微任务任务源
事件循环执行过程

先执行同步代码(script,也是个宏任务),遇到异步任务,将他们的具体执行任务放入对应的任务队列中,等同步代码执行完,查看微任务队列(microtask queue)是否有任务,有就循环执行直到微任务列表被清空,然后,执行ui渲染(ui render),之后,从宏任务队列中获取最先的一个任务放入执行栈执行,重复上述过程。

也就是: 宏任务 -> 微任务 -> 渲染,然后重复

事件循环的运行过程大致如下:

  1. 执行一个宏任务(执行栈中没有就从宏任务队列中获取)
  2. 执行过程中如果遇到微任务,则将其添加到微任务的任务队列中
  3. 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
  4. 当前宏任务执行完毕后,开始检查渲染,然后GUI线程接管渲染
  5. 当渲染完毕后,js 线程继续接管,开始下一个宏任务(从事件队列中获取)

同步任务
在主线程上排队执行的任务,只有前一个任务执行完毕之后,才能执行后一个任务。同步任务在主线程上执行时,形成一个执行栈。

包含以下形式:

  • 输出
  • 变量的声明
  • 同步函数等

异步任务
异步任务的回调会放入任务队列中,等待后续被调用。

以下会产生异步任务:

  • setTimeout和setInterval
  • DOM事件
  • Promise
  • ajax
  • fileReader
  • 异步函数等

宏任务
宏任务会加入到任务队列中(task queue),待同步代码执行完毕之后,执行栈从任务队列中获取最先加入的那个任务,放入执行栈执行。

以下产生的都是宏任务:

  • I/O
  • script(整体代码)
  • setTimeout
  • setInterval
  • UI交互事件
  • postMessage
  • MessageChannel
  • requestAnimationFrame

微任务
由微任务算法产生的任务会被加入到微任务队列(microtask queue)中,在执行栈执行完一个宏任务后,会去检查微任务队列,如果不为空,则执行所有微任务队列中的任务。

以下会产生微任务:

  • Promise.then
  • MutationObserver

目前先简单总结下,以后再深入了解。如果想深入了解可以去这里

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kkkkkaiqi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值