You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
由于resolve1内又resolve了一个Promise,所以在这里已经是异步任务了,而不是立即变为fulfilled的状态,所以console.log('b')并不是在第一轮事件循环中被加入微任务队列,而console.log('e')仍然是在第一轮事件循环中就被加入微任务队列,所以e先于b打印,最终打印顺序为a c d e b。
复杂异步嵌套逻辑分析
Async/Await 在事件循环中的表现
在分析之前,有必要了解一下
Async/Await
在事件循环中的表现,先看如下代码。不同chrome版本表现不同,有以下两种情况:
a c d b e
a c d e b
首先说明:最新ECMAScript规范下,第一种为正确表现,下面解释原因。
最新ECMAScript规范
最新ECMAScript规范中,
await
直接使用Promise.resolve()相同语义,也就是说,如果await
后跟的是一个Promise
,则直接返回Promise
本身,如果不是,则使用Promise.resolve
包裹后返回,上述代码执行过程可以简化理解为:console.log('b')
在第一轮事件循环时就加入微任务队列,然后console.log('e')
才加入微任务队列,故b
的打印顺序在先。老版ECMAScript规范
await
后不论是否为Promise
,都会产生一个新的Promise
,再将后面跟的内容resolve
出去。根据老版规范,上述代码执行过程可以简化理解为:
由于
resolve1
内又resolve
了一个Promise
,所以在这里已经是异步任务了,而不是立即变为fulfilled
的状态,所以console.log('b')
并不是在第一轮事件循环中被加入微任务队列,而console.log('e')
仍然是在第一轮事件循环中就被加入微任务队列,所以e
先于b
打印,最终打印顺序为a c d e b
。更多详细探讨可参考这篇文章。
复杂异步嵌套分析
async1
、async2
,打印script start
;setTimeout
,回调交由Web API
处理,Web API
将其加入宏任务队列;async1
,打印async1 start
;async2
,打印async2
,由于左边有await
,将console.log('async1 end')
放入微任务队列;new Promise
,同步执行传入构造函数的函数,打印promise1
;console.log('promise2')
所在函数放入微任务队列;script end
,当前任务执行完毕;async1 end
、打印promise2
;setTimeout
;故打印顺序为:
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
The text was updated successfully, but these errors were encountered: