今天,看了一个介绍js async/await 的博客文,https://www.cnblogs.com/bear-blogs/p/10423759.html。
前面的async和await的介绍,可以理解。但是,看到后面的执行顺序时,有些懵逼,懵逼的地方在顺序解说部分。
整段解说文字,只出现过一次,“推到微任务队列中”,后面的先后执行是什么鬼?没办法,这个博客能提到宏任务和微任务队列,比其他的博客,只说顺序的,多了知识点。我稍微修改一下代码进行测试。
async function test1() { console.log('start test1'); console.log(await test2()); console.log('end test1'); } async function test2() { console.log('test2'); //return await 'return test2 value' let x = await 'return test2 value';//这里修改一下 onsole.log("pass"); return x; } test1(); console.log('start async'); setTimeout(() => { console.log('setTimeout'); }, 0); new Promise((resolve, reject) => { console.log('promise1'); resolve(); }).then(() => { console.log('promise2'); }); console.log('end async');
经过自己琢磨和看其他博客之后。自己有了些想法,那就是,test1()执行,执行到await这行,右边是表达式,执行test2(),test2中,到了await 这里,由于右边是值了,自行转换Promise.resolve()中断,下一步恢复代码推到微任务队列。然后test1的await是等待test2的包裹Promise,然后阻塞后面,再先执行test1外面的。后面就同步输出promise1,将promise2推送到微任务队列。最后end async打印后,当前同步代码结束,轮到微任务队列执行。test2的await恢复执行,执行输出pass,返回,那么test2的async的Promise就执行resolve,test1 await等到值,将恢复代码推送到微任务列表。下一个微任务,promise2输出,再到test1的await恢复执行,正常执行输出。
这样就勉强理解了。然后我自己就在此基础上,复杂一点点的,来判断自己的理论。
async function test1_1() { console.log('start test1_1'); console.log(await test1_2()); console.log('end test1_1'); } async function test1_2() { console.log('test1_2'); let x = await test1_3(); console.log("end 1_2"); return x; } function test1_3(){ return new Promise((resolve, reject) => { console.log('test1_3'); resolve('return test1_3 value'); }) } async function test2_1(){ console.log('start test2_1'); console.log(await test2_2()); console.log('end test2_1'); } async function test2_2() { console.log('test2_2'); let x = await test2_3(); console.log("end 2_2"); return x; } async function test2_3(){ return new Promise((resolve, reject) => { console.log('test2_3'); resolve('return test2_3 value'); }) } async function test3_1(){ console.log('start test3_1'); console.log(await test3_2()); console.log('end test3_1'); } async function test3_2() { console.log('test3_2'); let x = await test3_3(); console.log("end 3_2"); return x; } async function test3_3(){ console.log('test3_3'); return await 'return test3_3 value'; } test1_1(); test2_1(); test3_1(); console.log('start async'); setTimeout(() => { console.log('setTimeout'); }, 0); new Promise((resolve, reject) => { console.log('promise1'); resolve(); }).then(() => { console.log('promise2'); return; }).then(()=>{ console.log('promise3'); }); console.log('end async');
很好,这顺序就有看头了,根据理解,test1和test3的路线都正常,目前是test2_3的输出不在预料,目前先这样,以后找到原因再修改。
稍微做了下测试,发现
//修改test2_3 //这个和未修改一样在promise3后面 async function test2_3(){ return Promise.resolve('return test2_3 value'); } //这个和理想一样,在end3_2前面 async function test2_3(){ return await Promise.resolve('return test2_3 value'); }