题目:
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();
console.log('script end')
请问打印出来的顺序是什么???
- 先不说结果,这个问题,如果是不了解js事件循环,宏任务与微任务的话,是没有头绪和眉目的
- 如果不了解JS事件循环,宏任务与微任务机制的建议先看看这篇文章,看完之后再来解题
- https://zhuanlan.zhihu.com/p/78113300
答案: ![在这里插入图片描述](https://img-blog.csdnimg.cn/4b0695223ba14603ae0a0c9a331fab5f.png)
解析:
- 先打印script start我觉得这个没有争议
- 然后遇到setTimeout,但是设置的时间是0,问题来了,会立马执行么
- 了解js宏任务之后,就发现最外层的函数执行是一个宏任务,遇到setTimeout后作为又一个宏任务压进栈里
- 但还是先要将自己这个宏任务去执行下去,所以会走async1(),那就再打印async1 start
- 然后async2其实是一个promise,但是因为async await可以认为是同步代码,但是其还是异步的
- 由于遇到await,会优先执行右边的async2(),那就再打印async2
- 但是继续执行,await async2()整体来说其实还是一个promise,所以,这个时候就产生了一个微任务
- 那么就优先执行之前的同步代码script end,然后该宏任务就只剩刚刚产生的微任务了
- 就打印async1 end,至此最外层的宏任务执行完毕,然后再执行下一个宏任务
- 然后加打印setTimeout
难点:
- 其实就算了解宏任务与微任务,有个问题也比较难以理解
- 为什么script end 会在 async1 end前打印
- 这个地方是有一定争议的,我认为await async2()是一个promise,形成了一个微任务,导致了先执行script end
- 但是也有人质疑是async await 的实现机制引起的
- 因为在实现async await中产生了生成器,其会自动的调用next()函数,产生了中断,才让script end先执行
- 这里我保留意见,按照我的思维去分析是没有问题的(希望有大佬来指正)