JS事件循环:微任务和宏任务

浏览器中 JavaScript 的执行流程和 Node.js 中的流程都是基于 事件循环 的。 理解事件循环的工作方式对于代码优化很重要,有时对于正确的架构也很重要。

事件循环是什么?

我们知道虽然 JavaScript 是一门单线程语言,但通过使用 Promise 等机制,可以实现异步编程,单线程与异步编程听起来是矛盾的,哪JS是如何实现异步编程呢,答案就是事件循环 。 事件循环 的概念非常简单, 件循环是 JavaScript 引擎用来处理异步任务的机制,在事件循环中,JavaScript 引擎会不断地从任务队列中取出任务,执行这些任务,并等待新的任务加入。 整体流程如下:

  1. 当同步代码时,引擎会顺序执行。
  2. 当碰到异步的代码时,引擎会将这个任务挂起,放入一个事件队列。
  3. 当同步代码执行完成后,主线程处于闲置状态时,主线程会去查找事件队列是否有任务,然后取出第一个任务,执行。
  4. 如此反复,形成事件循环。

常见的异步任务包括定时器、网络请求、事件监听器回调等。

从代码来看,js事件循环是采用类似下边这种方式来实现的:

javascript 复制代码
while (queue.waitForMessage()) {
  queue.processNextMessage();
}

关于宏任务、微任务

以上的事件循环过程是一个宏观的表述,实际上因为异步任务之间并不相同,因此他们的执行优先级也有区别。不同的异步任务被分为两类:微任务 (micro task)和宏任务 (macro task),在同一次事件循环中,微任务永远在宏任务之前执行。 以下事件属于宏任务:

  • setInterval()
  • setTimeout()

以下事件属于微任务

  • new Promise()
  • new MutaionObserver()

浏览器中有哪几种进程?

虽然js是单线程的,但js的执行环境浏览器并不是单线程的,浏览器中存在多个进程,每个进程负责不同的任务:

  • 主进程:管理浏览器的主要功能,如地址栏、书签、前进后退等。
  • 渲染进程:执行 JavaScript 代码、渲染页面、管理 DOM 元素等。
  • GPU 进程:处理页面的 GPU 相关操作,如绘制页面、动画效果等。
  • 网络进程:处理网络请求和数据传输。

其中渲染进程是执行js代码和渲染dom元素的进程,在渲染进程中,JavaScript 代码执行会影响页面渲染和用户交互。如果一个 JavaScript 任务执行时间过长,可能会阻塞其他任务的执行,导致页面卡顿,例如无法及时响应用户事件,例如处理用户事件。所以一些框架如React Fiber 架构采用将大任务拆分为小任务,并利用时间片的方式在渲染进程中交替执行这些任务,从而提高页面的响应性和用户体验。"

参考:

  1. 现代JavaScript教程-事件循环:微任务和宏任务
  2. 详解JavaScript中的Event Loop(事件循环)机制
相关推荐
枣把儿8 分钟前
开源!全套公众号写作、封面、发布自动化工具包!
前端·命令行
陶醉的松鼠12 分钟前
前端容易忽略的 debugger 调试技巧
前端
我命由我1234512 分钟前
6-3.Python 异常处理 - 异常处理进阶(else 块与 finally 块、异常传递、自定义异常)
开发语言·前端·数据库·后端·python·学习·java-ee
龙九山16 分钟前
我的 10 个 npm 插件,差点被 AI 判了死刑
前端·开源
deli00719 分钟前
键盘按键测试:按下就点亮,keydown 延迟精确到 1 毫秒
前端
Amos_Web26 分钟前
通过 Rspack 源码学 Rust(三):用 Default 与 std::mem::take 取出字段所有权
前端
MetWeave34 分钟前
风怎么流动:色斑告诉你多大,告诉不了你去哪
前端·数据可视化
Amos_Web35 分钟前
Rspack 源码解析(三十三):Module Federation 如何用 RemoteModule 与 ContainerEntryModule 表示远程代
前端
特立独行的猫A1 小时前
仓颉语言实现的Harness: 一口气派三个子代理,cjh 的并发不是“多线程“,是“进程树“
前端·harmonyos
Dumbness1 小时前
农历转换的 4 个边界:2 月 30 日能转出"正月十四"、小月没有三十、闰月、立春到春节之间的干支
前端·javascript