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

将Promise重构为Async/Await时为何出现undefined?

解决Async/Await重构后的串行问题与Undefined异常

咱们先直接定位问题根源:你重构后的longtime函数没有返回Promise,这导致await longtime()根本无法等待异步操作完成——因为await只能正确等待Promise对象,要是你给它一个非Promise值(比如这里的undefined,因为longtime没写return语句),它会直接把这个值包装成已resolve的Promise,相当于没等异步操作结束就继续执行后面的代码了,自然会打乱串行逻辑,甚至出现undefined相关的异常。

先理清楚原Promise代码为什么能串行

原代码里的one函数返回的Promise,会一直等到内部嵌套的Promise(包裹setTimeout的那个)执行完成后,才调用rs()来resolve自身,所以每次one().then(_ => one())都能保证前一个one完全执行完毕,才启动下一个,完美实现串行效果。

修复重构后的代码

我们只需要两步就能搞定:

第一步:修复longtime函数,让它返回Promise

async function one() {
  console.log('start');
  await longtime();
  console.log('endLong');
}

// 核心:让longtime返回Promise,才能被await正确等待
function longtime() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('after 3 sec');
      resolve(); // 异步操作完成后,手动resolve这个Promise
    }, 3000);
  });
}

小提示:longtime其实不需要加async关键字,因为它已经直接返回Promise了——加了也不报错,但没必要,反而手动返回Promise的逻辑更直观。

第二步:用Async/Await实现串行调用

原代码用.then()链式调用实现串行,换成Async/Await的话,我们可以写一个专门的执行函数,依次await每个one():

async function runSequence() {
  await one();
  await one();
  await one();
}

runSequence();

执行这段代码后,就会和原Promise代码的效果完全一致,依次输出:

start
after 3 sec
endLong
start
after 3 sec
endLong
start
after 3 sec
endLong

补充:为什么之前会出现undefined?

因为longtime没有返回值,默认返回undefined,await undefined会立即resolve,所以console.log('endLong')会在setTimeout的回调执行前就运行,同时one函数返回的Promise也会提前resolve,导致下一个one()提前启动,打乱了串行逻辑;另外在某些场景下,await undefined还可能触发和undefined相关的警告或错误。

内容的提问来源于stack exchange,提问作者Shakirov Ramil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:52:32