JavaScript事件循环是单线程异步处理核心机制,按“同步代码→微任务→宏任务”顺序循环执行;微任务(如Promise.then)在当前宏任务结束后立即清空,宏任务(如setTimeout)每次仅执行一个。

JavaScript事件循环是运行时处理异步操作的核心机制,它让单线程的JS能在不阻塞主线程的前提下执行定时器、网络请求、用户交互等任务。关键在于它严格区分同步代码、宏任务和微任务,并按固定顺序交替执行。
事件循环的基本流程
每次循环(tick)中,JavaScript引擎会:
- 执行当前调用栈中的所有同步代码
- 清空微任务队列(如 Promises.then、MutationObserver 回调)
- 从宏任务队列中取出一个任务执行(如 setTimeout、setInterval、I/O、UI渲染)
- 重复上述步骤
宏任务 vs 微任务
这是理解执行顺序的关键:
- 宏任务:script整体代码、setTimeout、setInterval、setImmediate(Node.js)、I/O、UI渲染。每次事件循环只处理一个宏任务
- 微任务:Promise.then/catch/finally、queueMicrotask、MutationObserver。只要微任务队列非空,就会持续执行直到清空
微任务总在当前宏任务结束后、下一个宏任务开始前执行,因此优先级更高。
立即学习“Java免费学习笔记(深入)”;
常见执行顺序示例
以下代码的输出顺序能直观体现事件循环规则:
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是宏任务,要等到下一轮循环才执行。
实际开发中的注意点
事件循环直接影响代码行为和性能表现:
- 避免在同步逻辑中长时间运行(如大循环),否则会阻塞微任务和UI更新
- 用 queueMicrotask 替代 setTimeout(fn, 0) 实现更及时的异步调度
- Vue/React 的响应式更新常利用微任务保证视图刷新时机一致
- Node.js 中 process.nextTick 比 Promise 微任务更早执行(仅限Node环境)
不复杂但容易忽略。










