JavaScript执行练习题
题目:写出以下代码的输出结果
console.log('1');
setTimeout(function() {
console.log('2');
new Promise(function(resolve) {
console.log('3');
resolve();
}).then(function() {
console.log('4')
})
setTimeout(function(){
console.log('5')
})
})
new Promise(function(resolve) {
console.log('6');
resolve();
}).then(function() {
console.log('7')
})
setTimeout(function() {
console.log('8');
new Promise(function(resolve) {
console.log('9');
resolve();
}).then(function() {
console.log('10')
})
setTimeout(function(){
console.log('11')
})
})
答案 :
1、6、7、2、3、4、8、9、10、5、11
解析:
- 整体script作为第一个宏任务进入主线程。
- 遇到
console.log(1),为同步任务,直接执行,输出1。 - 遇到
setTimeout为异步任务,任务执行结束后,判断其为宏任务,故将回调函数添加到宏任务事件队列,我们将它记为setTimeout1。 - 遇到
new Promise为异步任务,new Promise直接执行,输出6,任务执行结束后,判断其为微任务,故将then 方法绑
定的回调函数添加到微任务事件队列,我们将它记为then1。
- 遇到
setTimeout为异步任务,任务执行结束后,判断其为宏任务,故将回调函数添加到宏任务事件队列,我们将它记为setTimeout2。
| 宏任务Event Queue | 微任务Event Queue |
|---|---|
| setTimeout1 | then1 |
| setTimeout2 |
- 上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了
1和6。 - 询问微任务事件队列有没有要执行的任务,有,为
then1,执行,输出7。 - 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为
setTimeout1和setTimeout2。 - 执行
setTimeout1,首先遇见console.log(2),直接执行,输出2。 - 遇到
new Promise为异步任务,new Promise直接执行,输出3,任务执行结束后,判断其为微任务,故将then 方法绑
定的回调函数添加到微任务事件队列,我们将它记为then2。
- 遇到
setTimeout为异步任务,任务执行结束后,判断其为宏任务,故将回调函数添加到宏任务事件队列,我们将它记为setTimeout3。
| 宏任务Event Queue | 微任务Event Queue |
|---|---|
| setTimeout2 | then2 |
| setTimeout3 |
- 上表是第二轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了
7、2、3。 - 询问微任务事件队列有没有要执行的任务,有,为
then2,执行,输出4。 - 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为
setTimeout2和setTimeout3。 - 执行
setTimeout2,首先遇见console.log(8),直接执行,输出8。 - 遇到
new Promise为异步任务,new Promise直接执行,输出9,任务执行结束后,判断其为微任务,故将then 方法绑
定的回调函数添加到微任务事件队列,我们将它记为then3。
- 遇到
setTimeout为异步任务,任务执行结束后,判断其为宏任务,故将回调函数添加到宏任务事件队列,我们将它记为setTimeout4。
| 宏任务Event Queue | 微任务Event Queue |
|---|---|
| setTimeout3 | then3 |
| setTimeout4 |
- 上表是第三轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了
4、8、9。 - 询问微任务事件队列有没有要执行的任务,有,为
then3,执行,输出10。 - 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为
setTimeout3和setTimeout4。 - 执行
setTimeout3,首先遇见console.log(5),直接执行,输出5。
| 宏任务Event Queue | 微任务Event Queue |
|---|---|
| setTimeout4 |
- 上表是第四三轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了
10、5。 - 询问微任务事件队列有没有要执行的任务,没有。
- 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为
setTimeout4。 - 执行
setTimeout2,首先遇见console.log(11),直接执行,输出11
| 宏任务Event Queue | 微任务Event Queue |
|---|---|
- 上表是第五轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了
11。 - 询问微任务事件队列有没有要执行的任务,没有。
- 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,没有。
- 任务都执行完毕。
- 最终输出
1、6、7、2、3、4、8、9、10、5、11
作者:红尘炼心
链接:juejin.cn/post/684490…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。