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

Async/await是阻塞的吗?为何其运行结果与Promise写法存在差异?

Async/await非阻塞特性的常见误解解答

首先要明确async/await的「非阻塞」定义:它只会暂停当前async函数内部await语句之后的代码执行,不会阻塞整个JavaScript主线程的其他同步任务、事件回调执行,这才是非阻塞的核心含义,不是指不阻塞当前async函数内部的后续逻辑。

两种写法的执行流程差异

1. async/await写法执行顺序

function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  // 遇到await关键字
  const result = await resolveAfter2Seconds();
  console.log(result);
  console.log('calling end');
}

asyncCall();

执行流程:

  • 调用asyncCall(),首先同步执行console.log('calling'),输出calling
  • 执行resolveAfter2Seconds(),返回Pending状态的Promise,同时2秒延时的setTimeout进入宏任务队列等待执行
  • 触发await规则:暂停当前async函数后续所有代码的执行,立刻让出主线程(这就是非阻塞的体现,如果此时全局有其他同步代码会直接执行,不会等待2秒)
  • 2秒后Promise状态变为resolved,恢复执行async函数中await后的代码:先输出resolved,再输出calling end

2. Promise链式写法执行顺序

async function asyncCall() {
  console.log('calling');
  // 无await,直接执行Promise链式调用
  resolveAfter2Seconds().then(result=>{
    console.log(result);
  });
  console.log('calling end');
}

执行流程:

  • 调用asyncCall(),同步执行console.log('calling'),输出calling
  • 执行resolveAfter2Seconds().then(...),同样返回Pending状态的Promise,setTimeout进入宏任务队列
  • 没有await关键字,不会暂停当前async函数的执行,直接执行后续代码console.log('calling end'),输出calling end
  • 2秒后Promise状态变为resolved,执行then的回调函数,输出resolved

非阻塞特性的验证

你可以在asyncCall()调用后加一行全局同步代码测试:

asyncCall();
console.log('全局同步代码执行');

不管用await写法还是Promise链式写法,全局同步代码执行都会在calling之后立刻输出,不会等待2秒,这就是async/await非阻塞的直观体现。


内容的提问来源于stack exchange,提问作者Taimoor Hussain Musa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:45:02