JavaScript事件循环中宏任务包括全局脚本、setTimeout/setInterval回调等,微任务包括Promise.then、queueMicrotask等;执行顺序为:一个宏任务→全部微任务→下一个宏任务。

JavaScript 是单线程语言,靠事件循环(Event Loop)协调同步任务、异步回调的执行顺序。宏任务(Macrotask)和微任务(Microtask)是事件循环中两类关键任务,它们的执行顺序决定了代码的实际运行时序。
宏任务有哪些
宏任务是事件循环一次“迭代”中执行的主要任务,每次只取一个执行。常见宏任务包括:
- 全局脚本(初始执行的代码)
- setTimeout 和 setInterval 的回调
- setImmediate(仅 Node.js)
- I/O 回调(Node.js 环境)
- UI 渲染(浏览器环境,如重绘、重排)
- postMessage、MessageChannel 消息处理
微任务有哪些
微任务在**当前宏任务结束之后、下一个宏任务开始之前**立即执行,且会清空整个微任务队列。常见微任务包括:
- Promise.then/catch/finally 的回调(注意:Promise 构造器内的执行是同步的)
- queueMicrotask() 注册的函数
- MutationObserver 的回调(DOM 变化监听)
- await 后续代码(本质是 Promise 微任务的语法糖)
执行顺序规则
事件循环按以下固定节奏运转:
立即学习“Java免费学习笔记(深入)”;
- 执行一个宏任务(如 script、setTimeout 回调)
- 执行过程中遇到微任务,暂存到微任务队列
- 当前宏任务执行完后,立即依次执行所有已排队的微任务(直到队列为空)
- 浏览器可能进行 UI 渲染(可选,非强制步骤)
- 从宏任务队列中取出下一个宏任务,重复上述流程
关键点:微任务总在宏任务之间「插队」,且一次清空全部;宏任务之间不会插入其他宏任务。
典型例子看执行顺序
下面这段代码能清晰体现层级关系:
console.log(1); setTimeout(() => console.log(2), 0); Promise.resolve().then(() => console.log(3)); console.log(4);
输出顺序是:1 → 4 → 3 → 2。解释如下:
- 1 和 4 是同步代码,立即执行
- setTimeout 回调进入宏任务队列(等待下一轮)
- Promise.then 进入微任务队列
- 同步脚本结束后,立刻执行微任务:打印 3
- 然后取下一个宏任务:setTimeout 回调,打印 2










