You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

完整执行流程拆解

  1. 调用asyncCall(),进入这个async函数,执行到await resolveAfter2Seconds()。
  2. resolveAfter2Seconds()立刻返回一个未完成的Promise(因为setTimeout要等2秒才触发resolve)。这时await会做两件事:
    • 把asyncCall函数暂停挂起,不再往下执行;
    • 立刻把主线程的控制权交出去,让后面的代码继续跑。
  3. 主线程拿到控制权,直接执行console.log('Show at the end'),所以这句先打印出来。
  4. 2秒后,setTimeout的回调触发,Promise被resolve为'resolved'。此时事件循环会把之前挂起的asyncCall重新放到执行队列里。
  5. asyncCall恢复执行,把'resolved'赋值给result,然后依次执行console.log('calling')和console.log(result)。

关键知识点总结

  • async函数本身是异步的,调用它不会阻塞后续代码的执行;
  • await的作用域仅限当前async函数内部,它只是"暂停当前函数的执行",不是暂停整个程序;
  • JavaScript是单线程语言,所有异步任务(比如Promise、setTimeout)都会被放到事件队列里,等主线程空闲了再执行。await本质是把后续代码包装成Promise的then回调,加入异步队列。

内容的提问来源于stack exchange,提问作者Ae Leung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:31:02