我需要一些有关嵌套Observable的串联/管道化/分组的解释。
我有一个远程API / foo / bars / 100 ,该API会回复以下json对象
{
id: 100,
members: [{memberID: 1},..,{{memberID: N}]
}
我还有另一个API / members / $ {id} ,该API返回以下json:
{
id: ${id}
values: ['bla bla bla',...]
}
我想调用( GET )api / foo / bars / 100 ,然后遍历成员,并为每个成员调用( GET ) / members / $ {id} ,然后构建结果对象。
我想获得以下结果:
{
id: 100,
members: [
{
memberID: 1,
data: {
id: 1,
values: ['bla bla bla', ...],
}
},
{
memberID: 100,
data: {
id: 100,
values: ['bla bla bla', ...]
}
}
]
}
获得结果的最佳实践是什么?
答案 0 :(得分:1)
这是我的解决方案。 它按预期工作。
您有什么改进建议吗?
return dataService.getFooBars(100)
.pipe(
mergeMap((item) => {
const members = _.map(item.members, member => {
return dataService.getMemberByID(member.memberID)
.pipe(
map((memberData) => {
member.data = memberData;
return member;
})
);
});
return forkJoin(...members).pipe(
map(members => {
item.members = members;
return item;
})
);
})
)
答案 1 :(得分:0)
如果您希望一次加载所有成员的数据,则可以在成员加载后使用forkJoin。您也可以使用Promise.all()
答案 2 :(得分:0)
我只是自己学习RxJS的可观察性,并且我很乐意将您的问题作为个人练习来处理。我尚未对此进行测试,但是我认为这应该非常接近您如何以线性,功能化的方式将输入数据转换为所需的输出方式:
const fooBarID = 100;
const membersObservable
// { id: 100, members: [ {memberID: 1}, ..., {memberID: N} ] }
= dataService.getFooBars(fooBarID)
.pipe(
// => [ {memberID: 1}, ..., {memberID: N} ]
map(response => response.members),
// => [ 1, ..., N ]
map(listOfObjs => listOfObjs.map(obj => obj.memberID),
// => [ Observable<APIMember>(1), ..., Observable<APIMember>(N) ]
map(memberIDs => memberIDs.map(
memberID => dataService.getMemberByID(memberID)
)),
// => Observable<APIMember[]>
switchMap(memberObservables => forkJoin(...memberObservables)),
// => [ Member(1), ..., Member(N) ]
map(apiMembers => apiMembers.map(
apiMember => ({ memberID: apiMember.id, data: apiMember })
)),
// => { id: 100, members: [ Member(1), ..., Member(N) ] }
map(members => ({ id: fooBarID, members }))
);
如果您尝试一下,我很乐意听取您关于它是如何工作(或失败)的信息。