前端面试题之代码输出(十四)
  FTKwE7sqlksi 2023年11月02日 23 0

书接之前代码输出题目,

前端面试题之代码输出

前端面试题之代码输出二

前端面试题之代码输出三

前端面试题之代码输出四

前端面试题之代码输出五

前端面试题之代码输出六

前端面试题之代码输出七

前端面试题之代码输出八

前端面试题之代码输出九

前端面试题之代码输出十

前端面试题之代码输出十一

前端面试题之代码输出十二

前端面试题之代码输出十三


异步&事件循环
27.代码输出结果
console.log('1');

setTimeout(function () {
    console.log('2');
    process.nextTick(function () {
        console.log('3');
    })
    new Promise(function (resolve) {
        console.log('4');
        resolve();
    }).then(function () {
        console.log('5')
    })
})
process.nextTick(function () {
    console.log('6');
})
new Promise(function (resolve) {
    console.log('7');
    resolve();
}).then(function () {
    console.log('8')
})

setTimeout(function () {
    console.log('9');
    process.nextTick(function () {
        console.log('10');
    })
    new Promise(function (resolve) {
        console.log('11');
        resolve();
    }).then(function () {
        console.log('12')
    })
})

输出结果如下:

1
7
6
8
2
4
3
5
9
11
10
12

代码执行顺序如下:

(1)第一轮事件循环流程分析如下:

  • 整体script作为第一个宏任务进入主线程,遇到 console.log ,输出1。
  • 遇到 setTimeout ,其回调函数被分发到宏任务Event Queue中。暂且记为 setTimeout1
  • 遇到 process.nextTick() ,其回调函数被分发到微任务Event Queue中。记为 process1
  • 遇到 Promise , new Promise 直接执行,输出7。then 被分发到微任务Event Queue中。记为 then1
  • 又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,记为 setTimeout2

宏任务Event Queue

微任务Event Queue

setTimeout1

process1

setTimeout2

then

上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。发现了 process1then1 两个微任务:

  • 执行 process1 ,输出 6
  • 执行 then1 ,输出 8

第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。

(2)第二轮时间循环从 setTimeout1 宏任务开始:

  • 首先输出2。接下来遇到了 process.nextTick() ,同样将其分发到微任务Event Queue中,记为 process2
  • new Promise 立即执行输出4,then 也分发到微任务Event Queue中,记为 then2

宏任务Event Queue

微任务Event Queue

setTimeout2

process2


then1

第二轮事件循环宏任务结束,发现有 process2then2 两个微任务可以执行:

  • 输出3
  • 输出5

第二轮事件循环结束,第二轮输出2,4,3,5。

(3)第三轮事件循环开始,此时只剩setTimeout2了,执行。

  • 直接输出9。
  • process.nextTick() 分发到微任务Event Queue中。记为 process3
  • 直接执行 new Promise ,输出11。
  • then 分发到微任务Event Queue中,记为 then3

宏任务Event Queue

微任务Event Queue


process3


then3

第三轮事件循环宏任务执行结束,执行两个微任务 process3then3

  • 输出10
  • 输出12

第三轮事件循环结束,第三轮输出9,11,10,12。

整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。

28.代码输出结果
console.log(1)

setTimeout(() => {
    console.log(2)
})

new Promise(resolve => {
    console.log(3)
    resolve(4)
}).then(d => console.log(d))

setTimeout(() => {
    console.log(5)
    new Promise(resolve => {
        resolve(6)
    }).then(d => console.log(d))
})

setTimeout(() => {
    console.log(7)
})

console.log(8)

输出结果如下:

1
3
8
4
2
5
6
7

代码执行顺序如下:

  1. 首先执行script代码,打印出1;
  2. 遇到第一个定时器,加入到宏任务队列;
  3. 遇到Promise,执行代码,打印出3,遇到resolve,将其加入到微任务队列;
  4. 遇到第二个定时器,加入到宏任务队列;
  5. 遇到第三个定时器,加入到宏任务队列;
  6. 继续执行script代码,打印出8,第一轮执行结束;
  7. 执行微任务队列,打印出第一个Promise的resolve结果:4;
  8. 开始执行宏任务队列,执行第一个定时器,打印出2;
  9. 此时没有微任务,继续执行宏任务中的第二个定时器,首先打印出5,遇到Promise,首选打印出6,遇到resolve,将其加入到微任务队列;
  10. 执行微任务队列,打印出6;
  11. 执行宏任务队列中的最后一个定时器,打印出7。
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
FTKwE7sqlksi