乐趣区

今日头条网红题-????-async-functions-和-promises哪个更快

题目如下

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 结果一致。

退出移动版