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

如何在异步循环数据就绪后返回对象,避免返回空值?

问题分析与解决

你的代码存在两个核心问题:

  • forEach 不支持异步等待:forEach 会直接遍历执行回调,但不会等待回调里的 await 操作完成。函数执行到 return name_dates 时,循环里的异步请求还没结束,所以返回的是初始的空对象(你还错误地用对象初始化了数组类型的变量)。
  • 数组初始化错误:你把 name_dates 定义为 NameDates[] 数组类型,却用 {} 对象初始化,类型断言 <NameDates[]>{}; 无效,应该用数组字面量 []。

修正后的代码

async findAllScribesWithProfileName() {
  // ... 其他代码

  type NameDates = { display_name: string; created: Date[] };

  // 用map生成Promise数组,每个Promise处理一个owner的异步逻辑
  const nameDatesPromises = owners.map(async (owner) => {
    const profile = await this.profileService.getById(owner);
    const dates = scribes
      .filter((scribe) => scribe.owner === owner)
      .map((s) => s.created);
    
    return {
      display_name: profile.display_name,
      created: dates,
    };
  });

  // 等待所有异步操作完成,得到最终数组
  const name_dates = await Promise.all(nameDatesPromises);

  return name_dates;
}

关键改动说明

  1. 用 map 替代 forEach:map 会返回包含每个异步操作Promise的数组,方便后续用 Promise.all 等待全部完成。
  2. 使用 await Promise.all():确保所有获取profile的异步请求都执行完毕,再收集结果返回。
  3. 去掉多余的全局变量 name 和 dates:直接在每个异步回调内部声明变量,避免闭包导致的变量污染问题。
  4. 修正数组初始化逻辑:通过 Promise.all 直接生成目标数组,不需要提前初始化空数组。

如果坚持要按索引赋值(不推荐),也可以用支持异步等待的 for...of 循环:

async findAllScribesWithProfileName() {
  // ... 其他代码

  type NameDates = { display_name: string; created: Date[] };
  const name_dates: NameDates[] = [];

  for (let ownerIdx = 0; ownerIdx < owners.length; ownerIdx++) {
    const owner = owners[ownerIdx];
    const profile = await this.profileService.getById(owner);
    const dates = scribes
      .filter((scribe) => scribe.owner === owner)
      .map((s) => s.created);
    
    name_dates[ownerIdx] = {
      display_name: profile.display_name,
      created: dates,
    };
  }

  return name_dates;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:10:32