为何async/await代码中“Show at the end”先输出?求详解
async/await执行顺序困惑解析
你的核心误区是把await的作用范围想错了——它只会暂停当前async函数的执行,不会卡住整个JavaScript主线程,这就是为什么"Show at the end"先输出的原因。
先看你的代码:
function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 2000); }); } async function asyncCall() { const result = await resolveAfter2Seconds(); // 你以为程序会在这里停下来直到函数完成 console.log('calling'); console.log(result); } asyncCall(); console.log('Show at the end') // 你预期这句会最后输出,因为asyncCall里有await
运行结果:
Show at the end resolved calling
完整执行流程拆解
- 调用
asyncCall(),进入这个async函数,执行到await resolveAfter2Seconds()。 resolveAfter2Seconds()立刻返回一个未完成的Promise(因为setTimeout要等2秒才触发resolve)。这时await会做两件事:- 把
asyncCall函数暂停挂起,不再往下执行; - 立刻把主线程的控制权交出去,让后面的代码继续跑。
- 把
- 主线程拿到控制权,直接执行
console.log('Show at the end'),所以这句先打印出来。 - 2秒后,setTimeout的回调触发,Promise被resolve为'resolved'。此时事件循环会把之前挂起的
asyncCall重新放到执行队列里。 asyncCall恢复执行,把'resolved'赋值给result,然后依次执行console.log('calling')和console.log(result)。
关键知识点总结
- async函数本身是异步的,调用它不会阻塞后续代码的执行;
- await的作用域仅限当前async函数内部,它只是"暂停当前函数的执行",不是暂停整个程序;
- JavaScript是单线程语言,所有异步任务(比如Promise、setTimeout)都会被放到事件队列里,等主线程空闲了再执行。await本质是把后续代码包装成Promise的then回调,加入异步队列。
内容的提问来源于stack exchange,提问作者Ae Leung
相关产品推荐
相关产品推荐

