为何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
相关产品推荐
相关产品推荐

