第 32 题:深入理解事件循环(Event Loop)、微任务、宏任务(详细 + 难点 + 易错点)

好的,继续你的前端高频题训练。


第 37 题:深入理解事件循环(Event Loop)、微任务、宏任务(详细 + 难点 + 易错点)

这题在前端面试中属于 顶级高频题,并且往往是笔试 + 面试双重考。

我会讲:

  • 原理(你能向面试官讲清楚的那种)
  • 浏览器与 Node 的区别
  • 经典必考输出题
  • 容易被坑的知识点
  • 速记卡片

一、什么是事件循环(Event Loop)?

一句话:

JS 是单线程的,为了不阻塞任务执行,就通过事件循环机制来调度异步任务。

事件循环主要处理两类任务:

  • 宏任务(Macro task)
  • 微任务(Micro task)

二、宏任务 vs 微任务(非常关键)

✔ 宏任务(Macro task)

每一轮事件循环执行 一个 宏任务。

常见宏任务:

  • setTimeout
  • setInterval
  • setImmediate(Node)
  • I/O
  • UI 渲染
  • 整个 script 一次整体执行(没错,script 也是宏任务)

✔ 微任务(Micro task)

当一个宏任务执行结束后,会立即清空所有微任务队列。

常见微任务:

  • Promise.then / catch / finally
  • MutationObserver
  • queueMicrotask
  • Node 中还有 process.nextTick(优先级最高)

三、事件循环执行顺序(面试官最爱问)

一句话版流程:

复制代码
执行宏任务
  ↓
执行期间遇到微任务 → 放入微任务队列
  ↓
当前宏任务执行完 → 立即清空所有微任务
  ↓
进入下一轮宏任务

四、浏览器 vs Node 的区别(高频点)

浏览器事件循环:

复制代码
宏任务 → 微任务 → 渲染 → 下一轮宏任务

Node 事件循环更复杂,有六个阶段:

  1. timers
  2. pending callbacks
  3. idle, prepare
  4. poll
  5. check
  6. close callbacks

以及:

  • process.nextTick(优先级最高)
  • 然后才是微任务(Promise)

五、经典必考题(你必须会默写)


📌 例题 1:Promise vs setTimeout

javascript 复制代码
console.log(1);

setTimeout(() => console.log(2));

Promise.resolve().then(() => console.log(3));

console.log(4);

执行顺序:

1 → 4 → 3 → 2

解析:

  • 1、4:同步
  • 3:微任务
  • 2:宏任务

📌 例题 2:嵌套微任务

javascript 复制代码
Promise.resolve().then(() => {
  console.log('micro 1');
  Promise.resolve().then(() => console.log('micro 2'));
});

console.log('sync');

输出:

bash 复制代码
sync
micro 1
micro 2

原因:

微任务永远全部清空。


📌 例题 3:setTimeout vs Promise 再套 setTimeout

javascript 复制代码
setTimeout(() => console.log(1));

Promise.resolve().then(() => {
  console.log(2);
  setTimeout(() => console.log(3));
});

console.log(4);

顺序:

4 → 2 → 1 → 3

解释:

  • 4:同步
  • 2:微任务
  • 1:第一轮的宏任务
  • 3:Promise 里的 setTimeout → 第二轮宏任务

📌 例题 4:Node 特性 --- process.nextTick

javascript 复制代码
console.log(1);

setTimeout(() => console.log(2));

Promise.resolve().then(() => console.log(3));

process.nextTick(() => console.log(4));

console.log(5);

Node 输出:

arduino 复制代码
1
5
4   ← process.nextTick 优先级最高
3   ← 微任务
2   ← 宏任务

六、面试官深入追问(你必须会答)


❓为什么 Promise.then 会比 setTimeout 先执行?

因为 Promise 是微任务,而 setTimeout 是宏任务。

每一轮事件循环结束会立即执行所有微任务 → 永远先于宏任务。


❓微任务可以产生新的微任务吗?

可以,而且会继续在当前 microtask queue 中执行。


❓浏览器什么时候渲染?

一次事件循环中:

复制代码
宏任务 → 微任务 → (若需要则渲染)

渲染只在两次宏任务之间,不会打断微任务执行。


七、速记卡片(给你复习)


🟦 事件循环 --- 速记卡片

🟣 宏任务(一次执行一个)

  • script
  • setTimeout
  • setInterval
  • UI 渲染
  • I/O

🔵 微任务(每轮执行完宏任务就清空)

  • Promise.then
  • queueMicrotask
  • MutationObserver
  • (Node) process.nextTick(优先级最高)

🟢 执行顺序

复制代码
宏任务
→ 执行所有微任务
→ 渲染(浏览器)
→ 下一轮宏任务

🔴 Node 特殊优先级

arduino 复制代码
process.nextTick > Promise microtask > macrotask

要继续第 38 题吗?

下一题是:

👉 第 38 题:浏览器渲染流程(重排 Reflow、重绘 Repaint、合成 Compositing)

继续吗?

相关推荐
鹿心肺语20 分钟前
前端HTML转PDF的两种主流方案深度解析
前端·javascript
海石38 分钟前
去到比北方更北的地方—2025年终总结
前端·ai编程·年终总结
一个懒人懒人1 小时前
Promise async/await与fetch的概念
前端·javascript·html
Mintopia1 小时前
Web 安全与反编译源码下的权限设计:构筑前后端一致的防护体系
前端·安全
输出输入1 小时前
前端核心技术
开发语言·前端
Mintopia1 小时前
Web 安全与反编译源码下的权限设计:构建前后端一体的信任防线
前端·安全·编译原理
林深现海1 小时前
Jetson Orin nano/nx刷机后无法打开chrome/firefox浏览器
前端·chrome·firefox
黄诂多2 小时前
APP原生与H5互调Bridge技术原理及基础使用
前端
前端市界2 小时前
用 React 手搓一个 3D 翻页书籍组件,呼吸海浪式翻页,交互体验带感!
前端·架构·github
文艺理科生2 小时前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构