前端八股整理(代码输出 02)|宏任务微任务 promise await 代码输出题
前端八股整理(代码输出 02)|宏任务微任务 promise await 代码输出题
本文速览
一句话总结:
本文主要讲清楚 JavaScript 事件循环、宏任务、微任务、Promise 和 async/await 的执行顺序,帮助你理解代码输出题的核心判断逻辑,并能解决前端面试中常见的异步执行顺序题目。
适合人群:
适合正在准备前端面试、学习 JavaScript 异步机制、容易在 Promise / async / await 输出题中出错的同学阅读。
核心问题:
-
宏任务和微任务的执行顺序是什么?
-
Promise 的 executor 和 then 分别什么时候执行?
-
setTimeout、Promise、async/await 混在一起时应该怎么判断输出顺序?
-
面试中的异步代码输出题有哪些常见考点?
你将学会:
-
理解事件循环中宏任务和微任务的基本执行流程
-
掌握 Promise executor 同步执行、then 回调进入微任务队列的规则
-
理解 Promise 状态一旦改变就不可逆
-
理解 async / await 和 Promise.then 之间的关系
-
能够独立分析常见的 JavaScript 异步代码输出题
相关关键词:
JavaScript、事件循环、宏任务、微任务、Promise、async/await、setTimeout、代码输出题、前端面试
1.事件循环基础
1.1 宏任务与微任务执行顺序
执行顺序如下:
- 执行一次宏任务(最开始会是整个
srcipt所以上面的例子会先执行console.log(1)) - 执行过程中如果遇到宏任务,就放进宏任务列队
- 执行过程中如果遇到微任务,就放进微任务列队
- 当执行栈空了,先检查微任务列队,如果有微任务,就依序执行直到微任务列队为空
- 接着进行浏览器的渲染,渲然完后开始下一个宏任务(回到最开始的步骤)
1.2 Promise 执行机制
- promise中的执行器函数(executor)是同步执行的,也就是直接加入到执行栈中执行
- resolve 触发后,才将对应的.then 的部分加入微任务队列
- 如果既存在 resolve,又存在 reject,那么只会执行他们之中的第一个,因为Promise 状态一旦从
pending变成fulfilled,就不可能变成 fulfailed
1.3 setTimeout 执行机制
- setTimeout 加入宏任务队列中
1.4 async / await 执行机制
- await async2() 会同步立即执行 async2,并且把 await 后面的代码包装成一个「微任务」去执行
async/await可以理解成Promise.then()的语法糖await 后面跟一个普通函数的时候,会先正常执行,拿到返回值后,再用 Promise.resolve 包一层,然后后面的代码进行到微任务队列中继续执行
2.实战题目
2.1 模拟实战
给出下面代码的输出:
console.log('A');
const p = new Promise((resolve, reject) => {
// 这段就是 executor(执行器函数)
console.log('B: executor start');
resolve('OK');
console.log('C: executor end');
});
p.then((value) => {
console.log('E: then', value);
});
console.log('D');
A
B: executor start
C: executor end
D
E: then
console.log(1);
setTimeout(function () {
console.log(2);
}, 0);
Promise.resolve()
.then(function () {
console.log(3);
})
.then(function () {
console.log(4);
});
1
3
4
2
console.log("begins");
setTimeout(() => {
console.log("setTimeout 1");
Promise.resolve().then(() => {
console.log("promise 1");
});
}, 0);
new Promise(function (resolve, reject) {
console.log("promise 2");
setTimeout(function () {
console.log("setTimeout 2");
resolve("resolve 1");
}, 0);
}).then((res) => {
console.log("dot then 1");
setTimeout(() => {
console.log(res);
}, 0);
});
begins
promise 2
setTimeout 1
promise 1
setTimeout 2
dot then 1
resolve 1
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
console.log("script start");
setTimeout(function () {
console.log("setTimeout");
}, 0);
async1();
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("promise2");
});
console.log("script end");
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
2.2 真题实战
来源:腾讯音乐 暑期二面
new Promise((resolve, reject) => {
console.log("p1");
resolve();
console.log("p2")
reject();
}).then(() => {
console.log("then1");
new Promise((resolve, reject) => {
console.log("p2");
resolve();
}).then(() => {
console.log("then2");
}).then(() => {
console.log("then3");
});
}, () => {
console.log("then4")
})
p1
p2
then1
p2
then2
then3
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)