RxJS实现问题:遍历Group成员ID数组查询用户数据并合并至单个Group对象
RxJS实现问题:遍历Group成员ID数组查询用户数据并合并至单个Group对象
我明白你的问题了——你现在的代码会为每个成员生成一个独立的Group对象,而不是把所有成员数据整合到同一个Group里。问题出在你把Group对象和单个用户数据的合并逻辑放在了每个成员请求的map操作里,而不是等所有成员数据都获取完成后再一次性合并。
调整后的代码实现
this.groupService .getById(this.user.currentGroup) .pipe( mergeMap((group: IGroup) => { // 为每个成员ID创建用户数据请求,批量发起并行请求 const memberDataRequests = group.members.map((memberId) => this.userService.getById(memberId).pipe(take(1)) ); // 等所有用户请求完成后,将数据数组合并到原Group对象 return forkJoin(memberDataRequests).pipe( map((membersData: PublicUser[]) => ({ ...group, membersData // 将用户数据数组赋值给新的membersData属性 })) ); }) ) .subscribe((finalGroup) => { console.log(finalGroup); // 这里就能拿到你想要的单个Group对象结构了 });
核心逻辑说明
- 先获取原始Group对象:通过
groupService.getById拿到包含成员ID数组的基础Group数据 - 批量发起用户数据请求:用
map为每个成员ID生成对应的用户查询请求,再通过forkJoin并行执行所有请求(forkJoin会等待所有请求成功后,返回一个包含所有用户数据的数组) - 一次性合并数据:等所有用户数据返回后,在
map操作里将原始Group对象展开,同时添加membersData属性,值为获取到的用户数据数组 - 订阅得到最终结果:最后subscribe里拿到的就是单个完整的Group对象,完全符合你想要的输出结构
为什么原来的代码会出错?
你之前在每个成员请求的map里执行({ ...group, userData }),这相当于每个成员请求完成后,都复制一遍原始Group对象并只添加当前成员的数据,所以forkJoin最终收集到的是多个重复的Group对象(每个仅包含一个成员的详细数据)。而调整后的逻辑是等所有成员数据都齐了,再一次性合并到Group上,自然就得到了单个目标对象。
可选的类型优化
如果你的IGroup接口原本没有定义membersData属性,可以扩展一个新接口来保证类型安全:
interface GroupWithMembersData extends IGroup { membersData: PublicUser[]; }
然后在map时断言类型:
map((membersData: PublicUser[]): GroupWithMembersData => ({ ...group, membersData }))
备注:内容来源于stack exchange,提问作者Japhet
相关产品推荐
相关产品推荐

