async-await等待两个Promise为何总耗时4秒而非预期8秒?
核心认知偏差
你对Promise启动时机的理解存在错误:Promise实例在被new创建的瞬间,传入的执行器函数就会同步执行,内部的异步计时会立刻启动,await本身不会触发Promise任务启动,它的作用仅仅是暂停当前async函数的执行,等待对应Promise落定后再恢复后续逻辑。
你的代码实际执行流程
- 脚本从上到下同步运行,创建
promise1时,内部的4秒setTimeout立刻启动计时 - 紧接着创建
promise2,第二个4秒setTimeout也同步启动,两个计时器几乎同时开始倒计时 - 调用
asyncFunc()后,执行到await promise1时暂停函数,等待第一个Promise返回结果 - 4秒后第一个Promise触发resolve,函数恢复执行拿到
result1,继续执行到await promise2——此时第二个Promise的4秒计时早已和第一个并行跑完,状态已经是resolved,因此会直接拿到结果,不需要额外等待 - 两个结果几乎同时打印,总耗时仅4秒
实现串行8秒耗时的正确写法
不要提前创建好Promise实例,把Promise的创建逻辑封装为函数,等到需要执行对应异步任务时再调用函数生成Promise,就能实现串行等待的效果:
// 封装为工厂函数,调用时才会创建Promise、启动异步计时 function createPromise1() { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('Promise resolved1') }, 4000); }) } function createPromise2() { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('Promise resolved2') }, 4000); }) } async function asyncFunc() { // 第一次await时才创建第一个Promise,启动第一个4秒计时 let result1 = await createPromise1(); console.log(result1); // 第一个异步任务结束后才创建第二个Promise,启动第二个4秒计时 let result2 = await createPromise2(); console.log(result2); } asyncFunc();
额外提示:如果需要并行执行多个异步任务再统一等待结果,你提前创建所有Promise再用
Promise.all等待的写法反而是最优的,能最大程度压缩总耗时。
内容的提问来源于stack exchange,提问作者Rishabh singh
相关产品推荐
相关产品推荐

