反复横跳的await与Promise优先级

884 阅读2分钟

经典面试题之异步代码执行顺序

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');

往node里一放,很快啊,结果出了:

script start
async1 start
async2
promise1
script end
promise2
async1 end
settimeout

仔细思索一番,不对啊。😑async2本质是返回了个Promise.resolve()await的作用类似于用then取出了Promise中的值。后面这promise2凭什么比前面的async1 end早执行,那个async产生的promise应该先进微任务队列才是。难道是其中有什么奥秘?🤣🤣🤣

搜索一番

好家伙,这是道经典题。

image.png

结果非常amazing啊,竟然跟node环境不一样,这也太艹了。于是继续搜索,终于找到正主了# async/await 在chrome 环境和 node 环境的 执行结果不一致,求解?知乎上已有大神解答,总结起来就是

promise2和async1 end这俩顺序一直在变,以最新chrome为准 又想到,我电脑的默认node版本好像很低只有v10.10.0,nvm到新版试一下

script start
async1 start
async2
promise1
script end
async1 end
promise2
settimeout

顺序和浏览器一致了,我还有啥好说的呢💁💁💁

总结

其实async可以理解为返回了一个Promise.resolve(),await就负责结构出这个promise的值,同时堵塞后面的代码,其优先级应该是微任务的优先级。可通过下面代码验证

async function async1() {
    console.log("async1 start");
    await  async2();  
    console.log("async1 end");
}
function async2() { // 不用async了
    console.log( 'async2');
    return Promise.resolve(); // 用promise模拟
}
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');

结果还是一样的。最后指路一篇更完整的解析# 令人费解的 async/await 执行顺序。 最后的最后,吐槽一句:

都已经是异步了,还要整奇奇怪怪的顺序,咱写同步代码不行吗?😩😩😩 面试官你做个人吧!!!