当前位置: 首页 > news >正文

Javascript 中事件环以及宏任务微任务详细介绍

在 JavaScript 中,宏任务MacroTask) 和 微任务MicroTask) 是事件循环中任务调度的核心分类。

一、概述:事件环工作执行流程

第一步:执行同步代码
从调用栈中执行当前所有同步任务,直到调用栈清空。

第二步:清空微任务队列
依次执行微任务队列中的所有任务(包括执行过程中新产生的微任务),直到队列为空。

第三步:渲染更新(浏览器)
如果需要,浏览器会执行页面渲染(重绘、布局等)。

第四步:执行一个宏任务
从宏任务队列中取出队列头的第一个任务(如 setTimeout 回调),执行它。

第五步:重复循环
回到第一步,开启新的事件循环。

二、宏任务(MacroTask

宏任务代表需要较长时间执行的异步任务,每次事件循环中只执行一个宏任务(队列中的首个):

常见的宏任务:
setTimeout: 定时器回调函数(即使延迟为 0,也是宏任务)。
setInterval: 周期性定时器回调。
I/O 操作: 文件读写、网络请求(如 XMLHttpRequest、fetch 的回调)。
DOM 事件: 用户交互事件(如点击、滚动等)的回调。
requestAnimationFrame: 浏览器动画帧回调(通常归类为宏任务,但执行时机与渲染相关)。
script: 整体代码 初始执行的全局同步代码本身也是一个宏任务。
MessageChannel: 跨文档通信或 Web Worker 通信的回调。
Node.js 特有:
setImmediate: Node.js 中立即执行的宏任务(与 setTimeout(fn, 0) 类似,但有差异)。
I/O 回调 Node.js 中文件、网络等异步操作的回调

二、微任务(MicroTask

微任务具有更高优先级,会在当前宏任务执行后下一个宏任务执行前一次性清空队列

常见的微任务:
Promise.then/catch/finally : Promise 的异步回调(包括 async/await 的隐式转换)。
MutationObserver: 监听 DOM 变化的回调(浏览器环境)。
queueMicrotask: 显式将函数加入微任务队列的 API(如 queueMicrotask(() => { … }))。
Node.js 特有
process.nextTick Node.js 中优先级最高的微任务(甚至高于 Promise)

三、关键区别

请添加图片描述

四、执行顺序案例

1:基础顺序
console.log("Start"); // 同步代码(宏任务)

// 宏任务
setTimeout(() => console.log("Timeout"));

// 微任务
Promise.resolve().then(() => console.log("Promise"));

console.log("End"); // 同步代码(宏任务)
// 输出:

Start → End → Promise → Timeout
2:微任务嵌套
// 宏任务
setTimeout(() => console.log("Timeout"));

// 微任务(嵌套微任务)
Promise.resolve()
  .then(() => {
    console.log("Promise 1");
    Promise.resolve().then(() => console.log("Nested Promise"));
  })
  .then(() => console.log("Promise 2"));
// 输出:

Promise 1 → Nested Promise → Promise 2 → Timeout

五、特殊注意事项

Node.js 与浏览器的差异
Node.js 中 process.nextTick优先级高于 Promise.then。
Node.js 的 setImmediate 和 setTimeout(fn, 0) 执行顺序可能不同

微任务可能阻塞渲染
如果微任务队列过长,浏览器会在执行完所有微任务后才进行渲染,导致页面卡顿

避免微任务无限递归

function infiniteMicrotask() {
  Promise.resolve().then(infiniteMicrotask);
}
infiniteMicrotask(); // 会导致页面卡死

六、总结

宏任务:用于处理需要延迟执行或与外部交互的任务(如定时器、I/O)。

微任务:用于处理需要立即执行的高优先级任务(如 Promise 回调)。

以上内容如有错误之处,欢迎批评指正

相关文章:

  • VS2019 快捷键及各项功能汇总
  • 【GNN】0.环境配置
  • 【Pandas】pandas Index str
  • Quartus + VScode 实现模块化流水灯
  • 【Dive Into Stable Diffusion v3.5】1:开源项目正式发布——深入探索SDv3.5模型全参/LoRA/RLHF训练
  • DAPO:一个开源的大规模大型语言模型LLM强化学习系统
  • 案例驱动的 IT 团队管理:创新与突破之路: 第四章 危机应对:从风险预见到创新破局-4.1.1案例:某金融系统“重构生死战“
  • JAVA-多线程join()等待一个线程
  • 15 数据结构及算法应用
  • 【面试问题】Java 接口与抽象类的区别
  • python内置函数sorted
  • [解决] PDF转图片,中文乱码或显示方框的解决方案
  • CSS3 基础布局技术与响应式设计
  • JDK动态代理与CGLIB实现的区别?
  • 基于springboot的房屋租赁系统(008)
  • zabbix数据库溯源
  • 大语言模型的“细胞“:拆解语言模型的DNA——Token
  • P2786 英语1(eng1)- 英语作文
  • 生物医药行业百TB级数据同步的实战解决方案
  • 第7章:Docker容器网络模型深度剖析
  • 观察|本轮印巴冲突或促使印度空军寻求更先进战机
  • 甘肃发布外卖食品安全违法行为典型案例:一商家用鸭肉冒充牛肉被罚
  • 最新研究:新型合成小分子可“精准杀伤”癌细胞
  • 【社论】个人破产探索,要守住“诚实而不幸”的底线
  • 沙县小吃中东首店在沙特首都利雅得开业,首天营业额5万元
  • 广东韶关一镇干部冲进交通事故火海救人,获授“见义勇为”奖励万元