如何在异步循环数据就绪后返回对象,避免返回空值?
问题分析与解决
你的代码存在两个核心问题:
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; }
关键改动说明
- 用
map替代forEach:map会返回包含每个异步操作Promise的数组,方便后续用Promise.all等待全部完成。 - 使用
await Promise.all():确保所有获取profile的异步请求都执行完毕,再收集结果返回。 - 去掉多余的全局变量
name和dates:直接在每个异步回调内部声明变量,避免闭包导致的变量污染问题。 - 修正数组初始化逻辑:通过
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
相关产品推荐
相关产品推荐

