javascript浏览器中为单线程,事件循环按“执行一个宏任务→清空微任务队列→渲染→取下一个宏任务”顺序调度;宏任务包括settimeout、事件处理等,微任务如promise回调优先级更高,总在当前宏任务结束后立即执行。

JavaScript 在浏览器中是单线程执行的,任务队列(Task Queue)是协调异步操作的核心机制之一,它和调用栈、事件循环(Event Loop)协同工作,确保代码按预期顺序执行。
宏任务队列(Macrotask Queue)处理哪些操作
宏任务是事件循环每次“一轮”中执行一个的任务,常见来源包括:
- 全局脚本执行(页面加载时的顶层代码)
- setTimeout / setInterval 的回调函数
- UI 渲染任务(如重排、重绘,浏览器在每轮宏任务后自动插入)
- 用户交互事件(如 click、input、scroll 等绑定的事件处理器)
- postMessage、setImmediate(Node.js 环境,浏览器不支持)
微任务队列(Microtask Queue)优先级更高
微任务在**当前宏任务执行完、但尚未进入下一轮宏任务前**立即执行,且会清空整个微任务队列。常见来源有:
- Promise.then/catch/finally 的回调
- MutationObserver 的回调
- queueMicrotask() 显式添加的任务
例如:即使 setTimeout 设置为 0ms,它的回调也一定在所有 pending 的 Promise 回调之后执行。
事件循环如何调度任务
浏览器的事件循环持续运行,基本流程如下:
- 执行一个宏任务(如一个 click 回调或主脚本)
- 执行过程中遇到 Promise,把 .then 回调加入微任务队列
- 宏任务执行完毕,立即检查并依次执行全部微任务(直到队列为空)
- 浏览器可能进行一次 UI 渲染(非强制,但通常在此阶段)
- 从宏任务队列中取出下一个任务,重复上述过程
实际调试小技巧
想观察执行顺序?可以这样写一段测试代码:
console.log(1); setTimeout(() => console.log(2), 0); Promise.resolve().then(() => console.log(3)); console.log(4);
输出一定是:1 → 4 → 3 → 2。因为 1 和 4 是同步宏任务;3 是微任务,在同步代码结束后立刻执行;2 是下一个宏任务,要等本轮彻底结束才轮到。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











