前端八股文面经大全:26届秋招滴滴校招前端一面面经-事件循环题解析
- 前言
- 面经原文内容
- 事件循环面试题深度解析与面试官关键考察点
-
- [📝 **基础执行顺序分析**](#📝 基础执行顺序分析)
- [🔍 **面试官核心考察点**](#🔍 面试官核心考察点)
- [💡 **面试官追问方向**](#💡 面试官追问方向)
- [🎯 **候选人回答评价标准**](#🎯 候选人回答评价标准)
- [📚 **延伸学习建议**](#📚 延伸学习建议)
- [✨ **面试官提示**](#✨ 面试官提示)
- 结语
前言
大家好,我是木斯佳。
最近感触很深------在AI浪潮席卷之下,前端岗位肉眼可见地变少了,各大社区里的面经分享也没有前几年那么火热了。但我知道,依然有很多同学在努力准备面试,依然需要最新、最真实的前端面试资料。
市场需求在变,但学习的需求一直都在。
为此,我决定开这样一个专栏:专门收集整理最新的前端八股文和真实面经。并在原文基础上,增加面试官角度的问题,而不仅仅是静态的死记硬背。这样无论是校招还是社招,无论是大厂还是中小厂,只要是真实有价值的面试经历,都会在这里沉淀下来。
面经原文内容
题目代码
// 第一个 Promise 链
new Promise((resolve, reject) => {
console.log(1); // 同步输出
resolve(); // 解决 Promise
console.log(2); // 同步输出
})
.then(() => {
console.log(3); // 微任务
})
.then(() => {
console.log(4); // 微任务
setTimeout(() => { // 宏任务
console.log(5); // 宏任务内同步输出
new Promise((resolve) => {
resolve();
})
.then(() => {
console.log(6); // 宏任务内微任务
})
.then(() => {
console.log(7); // 宏任务内微任务链
});
}, 0); // 延迟设为 0
});
// 第二个独立的 Promise 链
new Promise((resolve) => {
resolve();
})
.then(() => {
console.log(8); // 微任务
})
.then(() => {
console.log(9); // 微任务
});
执行结果
代码执行后,控制台输出顺序为: 1, 2, 3, 8, 4, 9, 5, 6, 7
分析
JavaScript 的事件循环(Event Loop)机制决定了代码的执行顺序,主要分为同步任务、微任务(Microtask)和宏任务(Macrotask)。以下是逐步分析:
同步代码执行(立即执行):
- 执行第一个 new Promise的构造函数:输出 1,调用 resolve(),然后输出 2。
顺序输出:1, 2。 - 微任务队列处理(同步代码执行后,立即处理所有微任务):
第一个 Promise 的 resolve()将第一个 then回调(输出 3)加入微任务队列。
第二个 Promise 的 resolve()将第一个 then回调(输出 8)加入微任务队列。
此时微任务队列:[输出3, 输出8]。
- 处理微任务队列:
执行输出 3:输出 3。执行后,第一个 Promise 链的下一个 then(输出 4)被加入微任务队列。队列变为:[输出8, 输出4]。
执行输出 8:输出 8。执行后,第二个 Promise 链的下一个 then(输出 9)被加入微任务队列。队列变为:[输出4, 输出9]。
执行输出 4:输出 4。在执行中,遇到 setTimeout,将其回调函数(包含输出 5等)加入宏任务队列。执行后,无新微任务。队列变为:[输出9]。
执行输出 9:输出 9。
微任务队列清空。
- 宏任务队列处理(微任务队列空后,处理宏任务):
执行 setTimeout的回调函数(延迟为 0,但需等待微任务完成):
输出 5。
内部新 Promise 的 resolve()将 then回调(输出 6)加入微任务队列。
宏任务执行后,再次处理微任务队列:
微任务队列:[输出6]。
执行输出 6:输出 6。执行后,内部 Promise 链的下一个 then(输出 7)加入微任务队列。
执行输出 7:输出 7。
微任务队列清空。
最终输出顺序: 同步任务 → 微任务(按添加顺序)→ 宏任务 → 宏任务内产生的微任务。 因此顺序为:1, 2, 3, 8, 4, 9, 5, 6, 7。
事件循环面试题深度解析与面试官关键考察点
📝 基础执行顺序分析

代码执行流程分解:
【同步执行阶段】
1. 输出:1 (第一个Promise构造函数同步执行)
2. 输出:2 (继续同步执行)
【第一次微任务队列处理】
微任务队列初始:[then3, then8]
3. 输出:3 (执行第一个Promise的第一个then)
→ 新增微任务:then4
4. 输出:8 (执行第二个Promise的第一个then)
→ 新增微任务:then9
5. 输出:4 (执行then4)
→ 遇到setTimeout,回调加入宏任务队列
6. 输出:9 (执行then9)
→ 微任务队列清空
【宏任务处理】
7. 输出:5 (执行setTimeout回调的同步部分)
→ 新Promise resolve,then6加入微任务队列
【第二次微任务处理】
8. 输出:6 (执行then6)
→ 新增微任务:then7
9. 输出:7 (执行then7)
🔍 面试官核心考察点
层级一:基础概念理解(必考)
-
事件循环机制三要素
- 调用栈(Call Stack)
- 微任务队列(Microtask Queue)
- 宏任务队列(Macrotask/Task Queue)
-
任务分类标准
javascript// 宏任务示例 setTimeout, setInterval, I/O, UI rendering // 微任务示例 Promise.then/catch/finally, MutationObserver, queueMicrotask
层级二:执行细节把握
-
Promise构造函数的特殊性
javascriptnew Promise((resolve) => { console.log('同步'); // 同步执行 resolve(); // 状态改变,但回调不立即执行 console.log('还是同步'); // 继续同步 }) -
微任务的嵌套触发时机
- 一个微任务执行时,如果产生新的微任务,会加入当前微任务队列末尾
- 当前事件循环会持续执行微任务直到队列清空
层级三:易错点与陷阱
-
setTimeout延迟为0的实际含义
javascriptsetTimeout(fn, 0) // 实际意义:尽快执行,但必须等待: // 1. 当前同步代码执行完 // 2. 所有微任务执行完 // 3. 可能还有渲染任务等 -
Promise链式调用的状态传递
javascript// 关键:then返回新的Promise,状态取决于回调执行结果 Promise.resolve() .then(() => {}) // 返回undefined → fulfilled .then(() => {}) // 立即进入微任务队列
💡 面试官追问方向
追问1:如果调整代码顺序?
javascript
// 将第二个Promise移到最前面会怎样?
new Promise(resolve => resolve())
.then(() => console.log('A'))
.then(() => console.log('B'));
new Promise((resolve) => {
console.log(1);
resolve();
console.log(2);
})
.then(() => console.log(3))
.then(() => console.log(4));
// 答案:1, 2, A, 3, B, 4(思考为什么)
追问2:增加async/await
javascript
async function test() {
console.log(1);
await Promise.resolve().then(() => console.log(2));
console.log(3);
}
// await后的代码相当于在then回调中执行
追问3:浏览器与Node.js差异
javascript
// Node.js 11+ 与浏览器行为基本一致
// Node.js 11之前:微任务在宏任务间分批执行
🎯 候选人回答评价标准
优秀回答特征:
-
结构化表达
1. 同步代码 → 2. 微任务 → 3. 宏任务 → 4. 宏任务内的微任务 -
精准术语使用
- 区分"任务队列"与"微任务队列"
- 明确"事件循环的每一轮(tick)"
-
能解释原理而不仅是背结果
- 说明为什么是3,8而不是3,4
- 解释setTimeout延迟0的真正含义
常见扣分点:
- 混淆宏/微任务分类
- 忽略Promise构造函数同步执行
- 不理解微任务队列的连续清空机制
- 无法解释then链的状态传递
📚 延伸学习建议
实践验证方法:
javascript
// 1. 使用console.trace()追踪调用栈
// 2. 对比不同环境执行结果
// 3. 尝试修改代码验证理解
推荐深入理解:
-
ECMA规范相关章节
- Jobs and Job Queues (微任务规范)
- Event Loop Processing Model
-
实际应用场景
- Vue.nextTick实现原理
- React调度机制(Scheduler)
✨ 面试官提示
这道题的核心价值不在于记住具体输出顺序,而在于考察候选人:
- 能否系统化分析异步流程
- 是否理解事件循环的设计哲学
- 能否预见复杂异步场景下的执行顺序
在面试中,更看重候选人的分析过程而非最终答案。优秀的候选人会边分析边解释,展示其思考路径和知识体系完整性。
结语
欢迎投稿!
如果你有:
-
最近的面试经历
-
有挑战性的技术问题
-
对某个知识点的深度思考
-
学习路上的踩坑心得
都欢迎分享给我!每一篇投稿都会注明原文地址和作者,尊重每一位分享者的付出。
💪 我们相信:
- 即使岗位变少,技术的深度不会贬值。
- 即使行情波动,扎实的基础永远有用。
- 即使AI辅助,人的思考不可替代。
这个专栏,献给所有还在坚持、还在努力的前端开发者们。
一起加油。
原文链接lingchen111 分享