题目如下
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()
new Promise(function(resolve) {
console.log('promise1')
resolve()
}).then(function() {
console.log('promise2')
})
console.log('script end')
而v8和node10产出的结果有所不同。
v8运行结果?
node10运行结果?
先说下async/await原理?
- async 声明的函数,其返回值必定是 promise 对象,如果没有显式返回 promise 对象,也会用 Promise.resolve() 对结果进行包装,保证返回值为 promise 类型
- await 会先执行其右侧表达逻辑(从右向左执行),并让出主线程,跳出 async 函数,而去继续执行 async 函数外的同步代码
- 如果 await 右侧表达逻辑是个 promise,让出主线程,继续执行 async 函数外的同步代码,等待同步任务结束后,且该promise 被 resolve 时,继续执行 await 后面的逻辑
- 如果 await 右侧表达逻辑不是 promise 类型,那么 async 函数之外的同步代码执行完毕之后,会回到 async函数内部,继续执行 await 之后的逻辑
-- 摘自 LucasHC
看回题目的代码,同步任务执行下来打印出
script start
async1 start
async2
promise1
script end
同步任务结束后将跑回去执行await出来的东西,既然所有的async函数返回都是一个promise,所以 async function async2() {console.log('async2')}
应该返回的是一个Promise.resolve()
,此时将resolve后的then(() => {})
扔进去微任务列表,而微任务列表中已经有一个微任务了 ? then(function(){console.log('promise2')})
,所以先执行打印出promise2
,再执行then(() => {})
,然后await的代码才执行结束,进而执行下面的代码打印出async1 end
。
而以上是node10+的理解,如果放在v8,则会将 async function async2() {console.log('async2')}
理解为一个同步任务,也就是await async2()
等同于await console.log('async2')
,所以直接走await之后的逻辑打印出async1 end
,再跑微任务打印出promise2
。
如果手动添加async2
的返回结果为Promise.resolve()
,v8则和node结果一致。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。