第 1 题(入门必考题)
console.log(1);
setTimeout(() => {
console.log(2);
}, 0);
Promise.resolve().then(() => {
console.log(3);
});
console.log(4);
输出顺序:
1 4 3 2
解析:
- 先执行同步代码:
1、4 - 再执行所有微任务:
Promise.then → 3 - 最后执行宏任务:
setTimeout → 2
第 2 题(带 Promise 嵌套,高频)
console.log(1);
setTimeout(() => {
console.log(2);
Promise.resolve().then(() => {
console.log(3);
});
}, 0);
Promise.resolve().then(() => {
console.log(4);
});
console.log(5);
输出顺序:
1 5 4 2 3
解析:
- 同步:
1、5 - 微任务:
Promise.then → 4 - 宏任务:
setTimeout → 2- 执行宏任务内部时,遇到新的微任务
3,立即执行
- 执行宏任务内部时,遇到新的微任务
第 3 题(综合最难,面试压轴)
async function async1() {
console.log(1);
await async2();
console.log(2);
}
async function async2() {
console.log(3);
}
console.log(4);
setTimeout(() => {
console.log(5);
}, 0);
async1();
new Promise(resolve => {
console.log(6);
resolve();
}).then(() => {
console.log(7);
});
console.log(8);
输出顺序:
4 1 3 6 8 2 7 5
我给你来 4 道进阶版 Event Loop 面试题,包含:
async/await、Promise 嵌套、微任务套微任务、宏任务套宏任务,前端面试最难也就这样了。
你可以先自己做,再看答案解析。
第 4 题(微任务套微任务,经典坑)
Promise.resolve()
.then(() => {
console.log(1);
Promise.resolve().then(() => {
console.log(2);
});
})
.then(() => {
console.log(3);
});
setTimeout(() => {
console.log(4);
}, 0);
答案:1 2 3 4
解析:
- 先清空所有微任务,再执行宏任务
- 微任务里新加的微任务,会在本轮一起清空
第 5 题(await + 多层 Promise,大厂最爱)
async function fn() {
console.log(1);
await Promise.resolve();
console.log(2);
await Promise.resolve();
console.log(3);
}
console.log(4);
fn();
console.log(5);
答案:4 1 5 2 3
解析:
- await 前面:同步
- await 后面:微任务
- 多个 await 会按顺序进微任务队列
第 6 题(宏任务里套宏任务 + 微任务)
setTimeout(() => {
console.log(1);
setTimeout(() => {
console.log(2);
}, 0);
Promise.resolve().then(() => {
console.log(3);
});
}, 0);
setTimeout(() => {
console.log(4);
}, 0);
答案:1 3 4 2
解析:
- 一次只执行一个宏任务
- 执行完一个宏任务 → 清空微任务 → 再取下一个宏任务
第 7 题(综合地狱版,能做对就通关)
async function async1() {
console.log(1);
await async2();
console.log(2);
}
async function async2() {
console.log(3);
Promise.resolve().then(() => {
console.log(4);
});
}
console.log(5);
setTimeout(() => {
console.log(6);
}, 0);
async1();
new Promise((resolve) => {
console.log(7);
resolve();
}).then(() => {
console.log(8);
});
console.log(9);
答案:5 1 3 7 9 4 2 8 6
最终铁律(背会这 4 条,所有题都稳)
- 同步代码最先执行
- 每执行一个宏任务,就清空所有微任务
- 微任务里新增的微任务,本轮一起执行完
- await 后面 = 微任务
一句话总结:同步先跑完,微任务全清,再跑一个宏,循环永不停。
关键知识点:
async函数里 await 前面 是同步代码await后面的代码 = 微任务new Promise(() => {})里是同步代码.then()是微任务