一、题目描述
问:以下代码的输出顺序?
setTimeout(() => {
console.log(1);
}, 0);
setTimeout(() => {
console.log(2);
}, 1000);
(new Promise((resolve, reject) => {
console.log(3);
resolve();
(new Promise((resolve, reject) => {
console.log(6);
resolve();
})).then(() => {
console.log(7);
});
})).then(() => {
console.log(8);
});
setInterval(() => {
console.log(4);
},1000);
二、步骤分析
“①②③”表示分析代码的顺序
“1 2 3” 表示代码的执行输出顺序
// ① 宏任务
setTimeout(() => {
console.log(1); // 5
}, 0);
// ② 宏任务
setTimeout(() => {
console.log(2); // 6
}, 1000);
// ③ 初始化Promise时,传入的函数会被立即执行
(new Promise((resolve, reject) => {
console.log(3); // 1
// ④
resolve(); // 这里会触发then,但是then里面的回调函数添加到微任务队列的时机是在当前Promise内部的同步代码全部执行完之后,所以此时‘8’还没有被添加到微任务队列中
// ⑤ 同上,会立即执行
(new Promise((resolve, reject) => {
console.log(6); // 2
// ⑥
resolve(); // 触发then,并且此时当前Promise内部的同步代码已经全部执行完毕,所以此时‘7’添加进了微任务队列
})).then(() => {
console.log(7); // 3
});
})).then(() => { // 微任务
console.log(8); // 4
});
// ⑦ 宏任务
setInterval(() => {
console.log(4); // 7
},1000);
步骤分析:
1. 首先我们要知道微任务比宏任务先执行;
微任务包括:Promise,async/await
宏任务包括:setTimeout,setInterval,ajax,DOM事件
2. 所以先不管宏任务,我们现在看到new Promise()这一段里面
2.1 先执行console.log(3); ,然后遇到第一个resolve();,这里是重点!此时这里会触发then,但是then里面的回调函数添加到微任务队列的时机是在当前Promise内部的同步代码全部执行完之后,所以此时‘8’还没有被添加到微任务队列中;
2.2 继续执行第一个Promise里面的同步代码,也就是执行内层的Promise,就会先执行console.log(6);,然后遇到第二个resolve();,同样触发then,并且此时内层Promise内部的同步代码已经全部执行完毕,所以此时会将‘7’添加进微任务队列;
2.3 此时外层Promise内部的同步代码已经执行完毕,所以这时将then里面的回调函数添加进微任务队列,也就是‘8’是在‘7’之后被添加进微任务队列中的;
2.4 至此,new Promise()里面这一段代码就分析完毕。
3. 此时还没有被执行的代码就剩下微任务队列中的‘7’和‘8’,还有三个宏任务
3.1 先执行微任务,也就是输出‘7’和‘8’;
3.2 然后执行宏任务,1,2,4,4,4...
综上所述:
最终的执行顺序为:3 6 7 8 1 2 4 4 ...
三、答案展示
3 6 7 8 1 2 4 4 ...
四、更多
有关更多前端面试的知识可以查看我的有道云笔记前端面试知识,里面详细讲述了Promise,async/await,setTimeout等异步代码的相关知识,以及他们的输出顺序,了解完一定可以搞定异步相关面试题!大家一起加油!
如果以上内容对你有帮助,请点赞收藏吧❥(^_-),喜欢作者也可以加关注,后续会一直更新有关前端面试题的分享!