核心定义

宏任务 (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 个每次全部清空
优先级较低较高
典型 APIsetTimeout, setIntervalPromise.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

相关概念