之前在分享event loop的时候,有说到一个执行顺序问题,当时是在node v10版本下执行的,结果涉及到async await在ESMA规范上的变动,存在V8最新版本和稍老版本的差异,下面用当时的一段代码在node老版本和Chrome新版本下执行,看下结果:

Node版本:

执行结果:

Chrome版本:

执行结果:

可以看到promise2和async1 end的执行顺序在不同的版本下不一样,分享的时候我是按照上一个示例(node)老版本的结果分析的,当时并没有在Chrome上执行看一下,结果给大家造成了误导,在这里道一下歉。然后下来我分析了一下,出现这样的问题当时想的这个例子主要引出event loop,没有去做多方面的参考验证(其实再在Chrome上跑一下就可以发现的...)。下面说明一下两个版本执行结果不同的原因:

先贴一张ESMA规范上的变动图

分析一下,改动之后就是Promise.resolve(promise)和resolve(promise)的区别

那么 在上述的node版本

async function async1() {

    console.log('async1 start');

    await async2();

    console.log('async1 end');

}


async function async2() {

    console.log('async2');

}


//会被解析成


async function async1() {

    console.log('async1 start');

new Promise(resolve => {

    resolve(async2());

}).then(res => {

    console.log('async1 end');

})

}


async function async2() {

    console.log('async2');

}


//因为 async2() 返回 promise, 所以进一步转化就是:




async function async1() {

    console.log('async1 start');

new Promise(resolve => {

    Promise.resolve().then(() => {

      async2().then(resolve)

    })

}).then(res => {

    console.log('async1 end');

})

}


async function async2() {

    console.log('async2');

}


//而上述Chrome版本:


async function async1() {

    console.log('async1 start');

Promise.resolve(async2()).then(res => {

   console.log('async1 end');

})

}


async function async2() {

    console.log('async2');

}


//所以老的v8版本await后的代码会后于promise.then()执行。这里的v8版本可以Chrome浏览器版本参考,Chrome canary 73之前及其后。
编撰人:yinyanting、admin

快速跳转