前置知识: JavaScript

事件循环

1 minIntermediate2026/6/14

JavaScript事件循环机制详解

1. 事件循环基础

JavaScript 是单线程语言,事件循环是实现异步非阻塞的核心机制。

console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// 输出:1, 4, 3, 2

2. 宏任务与微任务

宏任务微任务
<script> 整体代码Promise.then/catch/finally
setTimeout/setIntervalMutationObserver
I/O 回调queueMicrotask
UI 渲染process.nextTick(Node.js)
setImmediate(Node.js)

执行顺序

  1. 执行同步代码(宏任务)
  2. 清空所有微任务
  3. 执行一个宏任务
  4. 重复 2-3
async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}

async function async2() {
  console.log('async2');
}

console.log('script start');
setTimeout(() => console.log('setTimeout'), 0);
async1();
new Promise((resolve) => {
  console.log('promise1');
  resolve();
}).then(() => console.log('promise2'));
console.log('script end');

// 输出:script start, async1 start, async2, promise1, script end,
//       async1 end, promise2, setTimeout

3. Node.js 事件循环

timers → pending → idle/prepare → poll → check → close callbacks
// process.nextTick 优先级最高
setImmediate(() => console.log('immediate'));
Promise.resolve().then(() => console.log('promise'));
process.nextTick(() => console.log('nextTick'));
// 输出:nextTick → promise → immediate

4. requestAnimationFrame

// rAF 在渲染前执行,跟随屏幕刷新率
function animate() {
  element.style.transform = `translateX(${x}px)`;
  requestAnimationFrame(animate);
}