题目如下asyncfunctionasync1(){console.log('async1start')awaitasync2()console.log('async1end')}asyncfunctionasync2(){console.log('async2')}console.log('scriptstart')setTimeout(function(){console.log('setTimeout')},0)async1()newPromise(function(resolve){console.log('promise1')resolve()}).then(function(){console.log('promise2')})console.log('scriptend')和v8和node10产生不同的结果。V8运行结果?Node10运行结果?先说说async/await的原理吧?async声明的函数的返回值必须是promise对象。如果未显式返回promise对象,结果也将使用Promise.resolve()进行包装。保证promise类型await的返回值会先执行右边(从右到左)的表达式逻辑,并放弃主线程,跳出async函数,继续执行async外面的同步代码功能。如果await右边的表达式逻辑是promise,则放开主线程,继续执行async函数外的同步代码,等待同步任务结束,当promiseresolve时,继续执行await背后的逻辑如果await右边的逻辑不是promise类型,那么async函数外面的同步代码执行完后,会回到async函数内部继续执行await之后的逻辑——摘自LucasHC的代码看题目,同步任务执行完后,打印出脚本startasync1startasync2promise1scriptend同步任务完成后,会跑回来执行await。由于所有异步函数都返回一个承诺,异步函数async2(){console.log('async2')}应该返回一个Promise.resolve(),然后(()=>{})进入微任务列表,并且有已经是微任务列表中的微任务了?then(function(){console.log('promise2')}),所以先执行并打印出promise2,然后执行then(()=>{}),然后执行await代码,然后是下面的代码执行打印出async1结束。以上是对node10+的理解。如果放在v8中,async函数async2(){console.log('async2')}会被理解为一个同步任务,即awaitasync2()等同于awaitconsole.log('async2'),所以await之后的逻辑直接打印出async1end,然后运行microtasks打印出promise2。如果手动添加async2的返回结果是Promise.resolve(),v8会和node的结果一致。
