js 异步执行顺序

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | console.log( 'script start' ) async function async1() { await async2() console.log( 'async1 end' ) } async function async2() { console.log( 'async2 end' ) } async1() setTimeout( function () { console.log( 'setTimeout' ) }, 0) new Promise(resolve => { console.log( 'Promise' ) resolve() }) .then( function () { console.log( 'promise1' ) }) .then( function () { console.log( 'promise2' ) }) console.log( 'script end' ) |
执行结果?
分析:
首先执行 同步代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | async function async1() { await async2() console.log( 'async1 end' ) } new Promise(resolve => { resolve() }) .then( function () { console.log( 'promise1' ) }) .then( function () { console.log( 'promise2' ) }) |
5. 然后根据先入先出的对列方式,先执行 await async2() 后面阻碍的函数 console.log('async1 end')
6. 执行promise的resolve函数
1 2 3 | new Promise(resolve => { resolve() }) |
也就是接下来的两个then: console.log('promise1') ---- console.log('promise2') ;
7. 最后执行的是 setTimeout函数 console.log('setTimeout') ;
综上所述,以上代码执行的顺序是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ( function () { setTimeout(() => { console.log(0); }); new Promise(resolve => { console.log(1); setTimeout(() => { resolve(); Promise.resolve().then(() => console.log(2)); console.log(3); }); Promise.resolve().then(() => console.log(4)); }).then(() => { console.log(5); Promise.resolve().then(() => console.log(8)); setTimeout(() => console.log(6)); }); console.log(7); })(); |
1. 同样先执行同步代码,且先把setTimeout去掉:
1 2 3 4 5 6 7 | new Promise(resolve => { console.log(1); Promise.resolve().then(() => console.log(4)); //微观任务 }).then(() => { //then函数是执行对应的 resolve 的时候才执行的 console.log(5); Promise.resolve().then(() => console.log(8)); //微观任务 }); console.log(7); |
可以看出先执行: console.log(1);console.log(7);
2. 执行微任务 Promise.resolve().then(() => console.log(4));
代码变成了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ( function () { setTimeout(() => { console.log(0); }); new Promise(resolve => { setTimeout(() => { resolve(); Promise.resolve().then(() => console.log(2)); console.log(3); }); }).then(() => { console.log(5); Promise.resolve().then(() => console.log(8)); //这句是多加的 setTimeout(() => console.log(6)); }); })(); |
只剩下宏观任务(微观任务在宏观任务里,也就是宏观任务外面不在有微观任务了)
3. 执行 console.log(0);
4.再执行 new Promise 中的 setTimeout,先执行里面的同步函数:console.log(3)
5. 再执行上面的 resolve,对应的是下面的then函数:
then(() => { console.log(5); Promise.resolve().then(() => console.log(8)); //这句是多加的 setTimeout(() => console.log(6)); }
所以先执行 console.log(5);
剩下的都是微观任务和宏观任务,先看微观任务:
1 2 3 4 5 6 7 | new Promise(resolve => { resolve(); Promise.resolve().then(() => console.log(2)); }).then(() => { Promise.resolve().then(() => console.log(8)); setTimeout(() => console.log(6)); }); |
所以根据队列中的微观任务顺序先执行:console.log(2),在执行then中的 console.log(8);
最后再执行 console.log(6)
综上所述,结果为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ( function () { setTimeout(() => { console.log(0); }); new Promise(resolve => { console.log(1); setTimeout(() => { resolve(); Promise.resolve().then(() => { console.log(2); setTimeout(() => console.log(3)); Promise.resolve().then(() => console.log(4)); }); }); Promise.resolve().then(() => console.log(5)); }).then(() => { console.log(6); Promise.resolve().then(() => console.log(7)); setTimeout(() => console.log(8)); }); console.log(9); })(); |

第二步: 执行微任务3,打印出 5;
第三步:执行宏任务1,打印出 0,
第四步:开始执行宏任务2;如图:



由图d的任务队列可知,
第七步:执行微任务6,打印出7;
第八步:执行微任务9,打印出4;
第九步:执行宏任务7,打印出8;
第十步:执行宏任务8,打印出3;
即答案是:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?