angular - RxJS - 使用 forEach 的多个请求并等待全部完成
问题描述
我有这种情况:
- 首先,我调用服务,并获取项目列表。(对象数组)
- 对于此列表中的每个项目,我调用另一个服务,它们实际上都可以并行触发。
- 我必须等待所有的答案。当我得到所有答案时,我有一个最终的逻辑。
我现在有这样的事情,但没有正确使用 RxJS:
this.service.readArray().subscribe((array: Object[]) => {
if (array.length > 0) {
array.forEach((item, index) => {
this.service2.readItem(item.id)
.subscribe(details => {
item.details = details;
// manually finally logic
if (index === array.length - 1) { // if the last iteration
...
}
}, (response: HttpErrorResponse) => {
...
// manually finally logic also for error part
if (index === array.length - 1) { // if the last iteration
...
}
});
});
} else {
... logic for no items in list
}
}, (error) => {
...
});
我如何在 Rxjs (5) 语句中表示这一点?
解决方案
您可以使用 forkJoin 等待所有调用完成。看起来您正在使用 rxjs 5 [正如您在问题中提到的那样],所以让我们像这样更改代码 [参见代码注释中的描述]:
this.service.readArray()
.switchMap(array => {
//lets map the array member to the respective observable
const obs$ = array.map(item => {
return this.service2.readItem(item.id)
.pipe(
catchError(err => {
//Do whatever you want to do with this error
//make sure to return an observable as per your logic. For this example, I am simply returning the err wrapped in an observable. Having catchError operator will gracefully handle the exception and make sure to emit the value as part of forkJoin.
return of(err);
})
)
});
//forkJoin will wait for all the readItem calls get finished.
return forkJoin(obs$);
})
.subscribe((finalArray) => {
//finalArray will be the array of object [an response of this.service2.readItem(item.id)]
console.log(finalArray);
//do whatever you want to do with the array
});
编辑 - 正如 OP 所要求的 - 掌握readArray
this.service.readArray()
.switchMap(array => {
//lets map the array member to the respective observable
const obs$ = array.map(item => {
return this.service2.readItem(item.id)
.pipe(
catchError(err => {
//Do whatever you want to do with this error
//make sure to return an observable as per your logic. For this example, I am simply returning the err wrapped in an observable. Having catchError operator will gracefully handle the exception and make sure to emit the value as part of forkJoin.
return of(err);
})
)
});
//forkJoin will wait for all the readItem calls get finished.
return forkJoin(obs$)
.pipe(
//return the original array along with joined using of
mergeMap((joined) => {
return of([array, joined]);
})
);
})
.subscribe((finalArray) => {
//finalArray will have readArray API response [i.e. array] at 0 index and on 1st index it will have joined array
console.log(finalArray);
//do whatever you want to do with the array
});
推荐阅读
- javascript - 在 ReactJS 中悬停图像的特定部分时如何更改鼠标光标?
- javascript - 连接 2 个数组意外结果
- reactjs - 自定义钩子和主要组件中的状态
- javascript - React:为什么批量更新不适用于异步作品?
- python - CVXPY 中具有优化变量的块矩阵
- c - GCC 发出的标签不会被该标签之外的任何东西跳转到?
- javascript - 检查是否所有异步 http 请求都已完成
- python - 如何通过 Hamming 或 Levenshtein 距离对字符串进行聚类
- linux - 在错误的家中创建目录
- python - 通过线性评估进行迁移学习:SimCLR,高损失值(损失:28494.7827)