如何解决使用MergeMap调用多个api并订阅数据 更新:API 调用对象中的多个属性
我需要调用一个 api,它将返回一个对象数组。然后我需要遍历所有对象并使用每个对象的 id 来调用另一个 api。然后我计划将数据保存在一个数组中并订阅,以便我可以访问包含来自两个 api 调用的数据的自定义数组。但是它对我不起作用。
我需要来自两个 api 调用的组合数据,但是在我创建的结果数组中,来自第二个 api 的数据显示为可观察的,当我尝试使用它们时,我收到未定义的错误。任何帮助将不胜感激。
this.apiService.getIntakeEvents(90430)
.pipe(mergeMap((res: any)=>{
const allData =[];
for(const item of res) {
let courseInfo = this.apiService.getSpecificCourse(item.courseId)
allData.push({...item,courseInfo})
}
console.log(allData)
return allData;
}))
.subscribe(res=> console.log(res))
解决方法
我们需要使用几个 RXJS 运算符来获得您想要的。
- 我们可以使用
mergeMap
来展平内部 observable - 然后我们使用
combineLatest
获取每个 API 调用的最新结果 - 然后我们在每个单独的 API 调用中使用
map
来返回item
及其相关的courseInfo
this.apiService
.getIntakeEvents(90430)
.pipe(
mergeMap((items) => {
return items.map((item) =>
this.apiService.getSpecificCourse(item.courseId).pipe(
map((courseInfo) => {
return {
item,courseInfo,};
})
)
);
})
)
.subscribe((res) => console.log(res));
,
您需要使用 forkJoin
、combineLatest
或 zip
等组合运算符来并行触发多个 observable。鉴于这是一个 API 调用,我认为 forkJoin
更适合这里,因为它仅在所有源完成后才发出。与他们here的短暂区别。
您还需要使用 Array#map
将对象数组转换为 HTTP 调用数组。之后,您可以使用 RxJS map
运算符对每个源 observable 转换回具有修改后的 courseInfo
属性的对象。
this.apiService.getIntakeEvents(90430).pipe(
mergeMap((res: any) =>
forkJoin(
res.map(item => this.apiService.getSpecificCourse(item.courseId)).pipe(
map(courseInfo => ({ ...item,courseInfo: courseInfo }))
)
)
)
).subscribe(
next: (res: any) => {
console.log(res)
},error: (error: any) => {
// handle error
}
);
更新:API 调用对象中的多个属性
要从外部 observable 更新对象中的多个属性,您可能必须使用包裹在外部 forkJoin
中的多个 forkJoin
。这当然只是一种方法,可能还有其他更好的方法。
示例
this.apiService.getIntakeEvents(90430).pipe(
mergeMap((res: any) =>
forkJoin({
courses: forkJoin(res.map(item => this.apiService.getSpecificCourse(item.courseId))),names: forkJoin(res.map(item => this.apiService.getSpecificName(item.courseId))),ages: forkJoin(res.map(item => this.apiService.getSpecificAge(item.courseId)))
}).pipe(map(({courses,names,age}) =>
res.map((item,index) => ({
...item,courseInfo: courses[index],name: names[index],age: ages[index]
})
))
)
).subscribe(
next: (res: any) => {
console.log(res)
},error: (error: any) => {
// handle error
}
);
,
你将不得不转换
this.apiService.getSpecificCourse(item.courseId);
来自 observable to a promise (您如何操作取决于您的 rxjs 版本,该版本包含在该链接中)。一旦它被转换为承诺,你就可以调用 .then() ,它允许你从回调中返回一个实际值。 observable 只允许您订阅,而不允许您从回调中返回值。
所以如果你有最新的 rxjs。你可以这样做:
let courseInfo = lastValueFrom(this.apiService.getSpecificCourse(item.courseId)).then((info) => info);
我认为应该有效
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。