【前端每天一题】🔥 第3题 事件循环 20 道经典面试题(附详细答案)

事件循环(Event Loop) - 前端面试核心题

这是前端面试最重要、最核心、最容易区分候选人水平的题之一。

0. 面试"标准一句话"版本

JS 是单线程语言,事件循环(Event Loop)负责协调同步任务、微任务(Promise)、宏任务(setTimeout等)的执行顺序;同步任务优先执行,之后每一轮循环都会先清空微任务队列,再执行一个宏任务,如此循环。

如果一分钟要答完,这样非常稳。

1. 为什么需要事件循环?(面试官很爱问)

因为:

  • JS 是单线程
  • 但浏览器要同时处理 UI 渲染、定时器、网络、用户输入等

所以必须用一个调度机制来"异步执行任务" → 这就是事件循环(Event Loop)

你的回答要提到"避免阻塞 UI" = 加分。

2. 事件循环的流程(核心逻辑)

事件循环的本质是:

同步任务 → 微任务 → 宏任务 → 微任务 → 宏任务 → ...

通常流程:

  1. 执行同步任务(栈)
  2. 清空所有微任务队列(microtask queue)
  3. 执行一个宏任务(macrotask queue)
  4. 再次清空微任务
  5. 再执行下一个宏任务
  6. 无限循环(Loop)

3. 宏任务 vs 微任务(必须背)

微任务(microtasks)

  • Promise.then/catch/finally
  • MutationObserver
  • queueMicrotask()
  • (Node)process.nextTick

宏任务(macrotasks)

  • setTimeout
  • setInterval
  • setImmediate(Node)
  • I/O 回调
  • UI 渲染事件
  • MessageChannel

口诀:微任务优先,Promise 是微任务。

4. 最经典的事件循环例题(90% 的面试官会问)

题 A:

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

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

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

console.log(4);

执行顺序:

复制代码
1
4
3
2

解释:

  • 同步:1 → 4
  • 微任务(then):3
  • 宏任务(setTimeout):2

题 B:Promise 中的多层微任务

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

输出顺序:

复制代码
1
2
3

解释: 每执行完一个 then,产生的微任务会加入同一轮的微任务队列中。

题 C:超级经典陷阱(setTimeout vs Promise)

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

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

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

console.log(4);

输出仍然是:

复制代码
1
4
3
2

哪怕 setTimeout 是 0,也永远比 Microtask 晚。

5. Event Loop 与浏览器渲染(加分项)

每一轮宏任务结束后,浏览器通常会进行:

  • 页面重绘(paint)
  • 布局计算(layout)
  • 样式计算(recalculate style)

所以: 微任务多了,会导致 UI 渲染被推迟(例如疯狂递归 Promise.then 会卡页面)

这是高级候选人的加分点。

6. Node.js 的事件循环(面试进阶)

你至少要答出:

Node 有自己的事件循环,与浏览器不同,基于 libuv,有 6 个阶段,每个阶段都有自己的队列;process.nextTick 优先级最高,属于独立队列。

面试官会觉得你"懂事件循环的底层原理"。

7. 面试优化版答题结构(满分答案)

  1. JS 是单线程,需要异步 → Event Loop 负责调度
  2. 同步任务先执行
  3. 之后清空微任务(Promise)
  4. 再执行一个宏任务(setTimeout)
  5. 每次宏任务执行后都会再清空一次微任务
  6. 微任务优先于宏任务
  7. Promise.then 是微任务;setTimeout 是宏任务
  8. Node.js 和浏览器略有不同(加分)

8. 前端事件循环的"核心口诀"

把这些背下来,任何场景都不会错。

  • 口诀 1: 同步先执行,Promise 比 setTimeout 快
  • 口诀 2: 每一轮宏任务后,必须清空微任务
  • 口诀 3: 0 秒定时器 ≠ 立即执行
  • 口诀 4: Promise 的 then 是微任务,await 也是微任务
  • 口诀 5: 微任务塞太多会卡 UI

9. 练习题(面试模拟)

练习 1:简单版

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

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

console.log(3);

顺序: 3、2、1

练习 2:进阶版

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

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

Promise.resolve().then(() => {
  console.log(4);
});

console.log(5);

顺序:

复制代码
1
5
4
2
3

练习 3:最经典"await"题

javascript 复制代码
async function test() {
  console.log(1);
  await console.log(2);
  console.log(3);
}
test();
console.log(4);

输出:

复制代码
1
2
4
3

await 把后面的部分拆成微任务。

相关推荐
前端一课1 小时前
【前端每天一题】第 2 题:var、let、const 的区别?(绝对高频)
前端·面试
前端一课1 小时前
【前端每天一题】🔥第四题 原型与原型链 - 前端面试必考题
前端·面试
初见0011 小时前
告别无限循环:深入理解并征服 React Hooks 的依赖数组
前端
一颗不甘坠落的流星1 小时前
【HTML】iframe 标签 allow 权限汇总(例如添加复制粘贴权限)
前端·javascript·html
亦草1 小时前
浅谈现代前端体系:组件化、模块化、类型系统与工程化
前端
IT_陈寒1 小时前
JavaScript开发者必知的7个ES2023新特性,让你的代码效率提升50%
前端·人工智能·后端
前端一课1 小时前
【前端每天一题】🔥 第 1 题:什么是 闭包(Closure)?它有什么作用?
前端·面试
j***63081 小时前
SpringbootActuator未授权访问漏洞
android·前端·后端
ze_juejin1 小时前
JavaScript事件循环总结
前端