之前在分享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
快速跳转
