Skip to content

01 事件循环机制 Event Loop

JS 是单线程的,但通过 Event Loop 实现了"假装多任务"——同步代码先跑完,然后处理微任务,最后处理宏任务,不断循环。

![[Screenshot 2026-03-16 at 12.33.38 PM.png]]

事件循环的组成部分

事件循环主要由以下几个部分组成: - 执行栈(Call Stack):当前正在执行的代码所在的栈。当函数被调用时,它会被推入执行栈;当函数执行完毕时,它会从执行栈中弹出。 - 当前正在跑的代码 - 事件队列(Event Queue)/宏任务队列(Macrotask Queue):存储异步事件的队列。当异步操作(如Ajax请求、定时器等)完成时,相关的回调函数会被放入事件队列中等待执行。 - setTimeout、setInterval、Ajax(优先级低) - 微任务队列(Microtask Queue):存储微任务的队列。微任务是在当前执行栈清空后,事件循环开始之前执行的任务。它们通常用于处理Promise回调等需要快速执行的轻量级任务。 - Promise.then、queueMicrotask(优先级高) 执行栈空了 → 把微任务队列全部清完 → 取宏任务队列里一个出来跑 → 再清微任务 → 循环

事件循环的过程

(1)执行代码:JavaScript引擎执行同步代码,并将函数调用放入执行栈中。  (2)处理微任务:当执行栈为空时,事件循环会检查微任务队列,并执行其中的回调函数,直到微任务队列为空。 (3)处理事件:微任务队列处理完毕后,事件循环会检查事件队列,并执行其中的回调函数,直到事件队列为空。 (4)重复步骤2和3:事件循环会不断重复这个过程,直到执行栈、微任务队列和事件队列都为空。

例子

console.log("开始");

setTimeout(() => {
  console.log("setTimeout");
}, 0);

Promise.resolve()
  .then(() => {
    console.log("第一个then");
  })
  .then(() => {
    console.log("第二个then");
  });

console.log("结束");

// 输出:
// 开始
// 结束
// 第一个then
// 第二个then
// setTimeout
  • 开始和结束都是同步,直接跑
  • setTimeout 的回调进宏任务队列
  • Promise.then 的回调进微任务队列
  • 同步跑完,先清微任务 → 打印 第一个then 第二个then
  • 两个 .then 都是微任务,会连续清完,才轮到 setTimeout。