跳到主要内容

Event Loop 执行机制过程:宏任务/微任务/渲染时机怎么讲?

面试速答(30 秒版 TL;DR)

  • JS 主线程按“事件循环”执行:取一个任务(task)执行到栈清空,然后清空微任务队列(microtask),必要时进行渲染,再进入下一轮。
  • 常见:setTimeout 属于任务队列(宏任务口径),Promise.then/queueMicrotask 属于微任务。
  • 口诀:一个 task 执行完 -> 清微任务 -> (可能)渲染 -> 下一个 task
  • 浏览器与 Node 的具体队列实现不同,但“微任务优先于下一个任务”的核心规律一致。

浏览器端的执行流程(面试口述版)

常见来源(面试只要会举例):

  • task:setTimeout、用户事件回调、网络事件回调等
  • microtask:Promise.then/catch/finallyqueueMicrotaskMutationObserver(浏览器)

经典输出题:解释执行顺序

console.log("A");

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

Promise.resolve()
.then(() => console.log("P1"))
.then(() => console.log("P2"));

console.log("B");

答案:A B P1 P2 T

解释要点:

  • 同步先跑完:A、B。
  • 再清微任务:P1、P2(链式 then 也是微任务排队)。
  • 最后下一个任务:T。

常见追问:requestAnimationFrame 在哪?

面试口径即可:

  • requestAnimationFrame 回调通常在下一次渲染前执行,适合做动画帧同步更新。
  • 它和 setTimeout 最大区别是:它与渲染节奏对齐,且后台标签页会被降频/暂停。

易错点/坑

  • 把 Promise 回调当成“宏任务”:在浏览器里它是微任务,优先级更高。
  • 只背输出不讲原因:输出题必须用“task -> microtask”的模型解释。

速记要点(可背诵)

  • 一轮循环:task 执行完 -> 清空 microtask ->(可能)渲染 -> 下一轮。
  • setTimeout task,Promise.then microtask。