我们如何重构以下代码以删除使用behaviorsubjects的链接,以便一个函数调用的失败不会影响使用其他函数调用的数据的UI?
this.service.getElementById(this.elementId)
.pipe(mergeMap((element) =>
zip(
of(element),
this.service.getReport(this.elementId, this.year, this.month)
))
)
.pipe(mergeMap(([element, report]) =>
zip(
of(element),
of(report),
this.service.getChanges(this.elementId, report.lineId)
))
)
.subscribe(([element, report, changes]) => {
this.paymentProvider = provider;
this.mapToSummary(report);
this.lineId = report.lineId;
this.changes = changes;
})
以下是实现此目标的方法:
this.service
.getElementById(this.elementId)
.pipe(
mergeMap((element) => {
const report$ = this.service
.getReport(this.elementId, this.year, this.month)
.pipe(
catchError(() => of(null)),
shareReplay({ bufferSize: 1, refCount: true })
);
const changes$ = report$.pipe(
mergeMap((report) =>
!report
? null
: this.service
.getChanges(this.elementId, report.lineId)
.pipe(catchError(() => of(null)))
)
);
return forkJoin({
element: of(element),
report: report$,
changes: changes$,
});
})
)
.subscribe(({ element, report, changes }) => {
// do whatever you want here
// remember that now report and changes can be null
});
这将确保如果有任何失败,整个可观察结果不会出错。