为何两段含async/await的JavaScript代码执行表现截然不同?
两段async/await代码的执行差异解析
代码示例
代码1
async function test(){ const a1 = await new Promise((res,rej)=>{ setTimeout(()=>{ return res("5 second promise") },5000) }) console.log("first") const a2 = await new Promise((res,rej)=>{ setTimeout(()=>{ return res("2 second promise") },2000) }) console.log("second") } test();
代码2
const p1 = new Promise((res,rej)=>{ setTimeout(()=>{ return res("5 second promise") },5000) }) const p2 = new Promise((res,rej)=>{ setTimeout(()=>{ return res("2 second promise") },2000) }) async function test2(){ await p1; console.log("first") await p2; console.log("second") } test2();
执行表现
- 代码1:5秒后打印
first,再过2秒打印second - 代码2:5秒后同时打印
first和second
疑问解答
1. 为何两段代码的执行行为存在明显差异?
核心区别是Promise的创建时机:
- 代码1的两个Promise都在
async函数内部、第一个await完成后才依次创建,属于串行启动; - 代码2的
p1和p2在async函数执行前就已创建完成,属于并行启动。
2. await会暂停当前async函数,为何代码2中延迟2秒的await p2与延迟5秒的await p1同时完成,而非在p1完成后再过2秒才打印“second”?
因为p2的Promise在test2函数执行前就已经启动了内部的setTimeout,当await p1等待5秒完成时,p2的setTimeout已经提前运行了5秒(实际2秒就完成了),此时p2的状态已经是已兑现,await p2会直接跳过等待,立即执行后续的console.log("second"),最终和first几乎同时打印。
3. 是什么核心差异导致代码1按预期的顺序执行?
代码1中,第二个Promise是在第一个await完成、打印first之后才被创建的,此时它内部的setTimeout才开始计时,必须等2秒后Promise兑现,才会执行console.log("second"),完全是串行执行逻辑。
额外疑惑:async函数在await处暂停,为何代码2中p2的计时会与p1同时启动,明明p2对应的await代码还未执行到?
Promise的核心特性是创建即执行:当调用new Promise(executor)时,传入的执行器函数会立即同步执行,里面的setTimeout会被立刻推入定时器队列开始计时,和后续的await无关。代码2里p1和p2在全局作用域创建,所以它们的定时器在脚本加载时就同时启动了,和test2函数的执行、await的暂停没有关系。
内容的提问来源于stack exchange,提问作者x072ux73hx69
相关产品推荐
相关产品推荐

