JavaScript执行练习题

148 阅读4分钟

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
setTimeout1then1
setTimeout2
  • 上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了16
  • 询问微任务事件队列有没有要执行的任务,有,为then1,执行,输出7
  • 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为setTimeout1setTimeout2
  • 执行setTimeout1,首先遇见console.log(2),直接执行,输出2
  • 遇到new Promise为异步任务,new Promise直接执行,输出3,任务执行结束后,判断其为微任务,故将then 方法绑

定的回调函数添加到微任务事件队列,我们将它记为then2

  • 遇到setTimeout为异步任务,任务执行结束后,判断其为宏任务,故将回调函数添加到宏任务事件队列,我们将它记为setTimeout3
宏任务Event Queue微任务Event Queue
setTimeout2then2
setTimeout3
  • 上表是第二轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了723
  • 询问微任务事件队列有没有要执行的任务,有,为then2,执行,输出4
  • 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为setTimeout2setTimeout3
  • 执行setTimeout2,首先遇见console.log(8),直接执行,输出8
  • 遇到new Promise为异步任务,new Promise直接执行,输出9,任务执行结束后,判断其为微任务,故将then 方法绑

定的回调函数添加到微任务事件队列,我们将它记为then3

  • 遇到setTimeout为异步任务,任务执行结束后,判断其为宏任务,故将回调函数添加到宏任务事件队列,我们将它记为setTimeout4
宏任务Event Queue微任务Event Queue
setTimeout3then3
setTimeout4
  • 上表是第三轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了489
  • 询问微任务事件队列有没有要执行的任务,有,为then3,执行,输出10
  • 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为setTimeout3setTimeout4
  • 执行setTimeout3,首先遇见console.log(5),直接执行,输出5
宏任务Event Queue微任务Event Queue
setTimeout4
  • 上表是第四三轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了105
  • 询问微任务事件队列有没有要执行的任务,没有。
  • 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,有,为setTimeout4
  • 执行setTimeout2,首先遇见console.log(11),直接执行,输出11
宏任务Event Queue微任务Event Queue
  • 上表是第五轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了11
  • 询问微任务事件队列有没有要执行的任务,没有。
  • 微任务队列都执行完毕了,询问宏任务事件队列有没有要执行的任务,没有。
  • 任务都执行完毕。
  • 最终输出1672348910511


作者:红尘炼心
链接:juejin.cn/post/684490… 来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。