核心定义
宏任务 (MacroTask) 是 JavaScript 事件循环中的任务单位,每次事件循环从宏任务队列中取出一个任务执行。宏任务是相对于微任务而言的粒度较大的任务。
核心命题
任务粒度 :宏任务是较大的任务单位,每次事件循环执行一个
执行时机 :在当前宏任务执行完毕后,才会执行微任务队列
浏览器渲染 :部分宏任务(如 requestAnimationFrame)会触发浏览器渲染
阻塞风险 :大量同步宏任务会阻塞事件循环,导致页面卡顿
运行机制
执行流程
flowchart TD
A[事件循环开始] --> B{宏任务队列<br/>有任务?}
B -->|是| C[取出1个宏任务]
B -->|否| D[等待新任务]
C --> E[执行宏任务]
E --> F{产生微任务?}
F -->|是| G[加入微任务队列]
F -->|否| H[执行完所有微任务]
G --> H
H --> I{需要渲染?}
I -->|是| J[浏览器渲染]
I -->|否| K{宏任务队列<br/>有任务?}
J --> K
D -->|新任务| A
style C fill:#f99,stroke:#333
style H fill:#9ff,stroke:#333
常见宏任务
API 说明 备注 setTimeout定时器 延迟至少 4ms setInterval间隔定时器 可能累积延迟 setImmediateNode.js 立即执行 仅 Node.js requestAnimationFrame渲染帧回调 在渲染前执行 I/O 操作 文件/网络读写 Node.js 特有 UI 渲染 DOM 更新 浏览器特有
关键区别
宏任务 vs 微任务
特征 宏任务 (MacroTask) 微任务 (MicroTask) 执行时机 每个事件循环阶段 每个宏任务结束后 执行数量 每次 1 个 每次全部清空 优先级 较低 较高 典型 API setTimeout, setInterval Promise.then 阻塞渲染 可能阻塞 不阻塞渲染
与 微任务 的执行顺序
sequenceDiagram
participant M as 宏任务
participant m as 微任务
participant R as 渲染
M->>M: 执行宏任务
M->>m: 产生微任务
m->>m: 清空微任务队列
m->>R: 渲染(如需要)
R->>M: 下一轮事件循环
应用场景
适用场景
定时任务 :需要延迟执行的操作
轮询 :周期性检查状态
渲染控制 :需要与浏览器渲染同步的操作
注意事项
setTimeout(0) :并非立即执行,至少 4ms 延迟
setInterval :长时间运行可能累积延迟
大量同步代码 :会阻塞事件循环,导致页面无响应
requestAnimationFrame :适合动画,但回调数量有限制
知识图谱
flowchart TB
EL[事件循环<br/>Event Loop] --> MT[宏任务<br/>MacroTask]
EL --> mTask[微任务<br/>MicroTask]
MT -->|示例| ST[setTimeout]
MT -->|示例| SI[setInterval]
MT -->|示例| rAF[requestAnimationFrame]
MT -->|示例| IO[I/O]
mTask -->|优先级更高| EL
ST -->|组成| JS[JavaScript]
SI -->|组成| JS
rAF -->|组成| JS
IO -->|组成| JS
style MT fill:#f99,stroke:#333
style mTask fill:#9ff,stroke:#333
style EL fill:#ff9,stroke:#333
相关概念