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

为何await不会延迟阻塞?探究其立即阻塞而非按需阻塞的原因

为什么await会立即阻塞(而非引用值时才延迟)?

嘿,这个问题问得特别到位,完全在讨论范围内,不用道歉哈!这其实是很多人刚接触异步编程时容易混淆的点,核心原因在于Promise的执行时机和await的作用边界,咱们一步步拆解:

核心本质:Promise创建时就启动了异步任务

你的delayedValue函数一被调用,就会立刻创建Promise并启动里面的定时器——await只是在等待这个已经在运行的Promise完成,而不是等到你要用到值的时候才触发任务执行。

先修正你代码里的小拼写错误(val应该是value),然后看这个示例:

let delayedValue = (value, ms=1000) => {
  return new Promise(resolve => {
    setTimeout(() => resolve(value), ms);
  });
};

(async () => {
  console.log('开始执行');
  const myVal = delayedValue('测试结果'); // !!这里一调用,定时器就已经开始计时1000ms了!!
  await new Promise(resolve => setTimeout(resolve, 500)); // 先等500ms做别的事
  console.log('准备获取异步值');
  const result = await myVal; // 这里只需要再等500ms,因为定时器已经跑了一半
  console.log(result);
})();

运行这段代码你会发现,从“开始执行”到打印“测试结果”,总共只花了1000ms,而不是1500ms——这就证明异步任务在调用delayedValue的时候就启动了,await只是在等它结束,不是触发它开始。

如何实现“引用值时才延迟阻塞”?

如果想让任务在你真正需要值的时候才启动,你需要把Promise包装成一个待执行的函数,而不是直接返回Promise:

let delayedValue = (value, ms=1000) => {
  // 返回一个函数,而不是直接返回Promise
  return () => new Promise(resolve => {
    setTimeout(() => resolve(value), ms);
  });
};

(async () => {
  console.log('开始执行');
  const getMyVal = delayedValue('测试结果'); // 这里只是拿到了函数,定时器还没启动
  await new Promise(resolve => setTimeout(resolve, 500)); // 先等500ms做别的事
  console.log('准备获取异步值');
  const result = await getMyVal(); // !!这里才调用函数,启动定时器,需要等1000ms!!
  console.log(result);
})();

这次运行的话,从“开始执行”到打印结果,总共会花1500ms——完全符合你想要的“用到值的时候才开始延迟”的效果。

总结一下

  • await的作用是暂停当前async函数的执行,直到目标Promise状态变为resolved,它不负责控制异步任务的启动时机;
  • Promise本身代表的是一个已经在进行中的异步操作,一旦创建就会开始执行;
  • 要实现“按需执行”,就把Promise的创建逻辑包装成函数,在需要的时候调用函数再await。

内容的提问来源于stack exchange,提问作者Gershom Maes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:47:14