如何使用行为主体删除此代码中的链接?

How to remove chaining in this code using behavior subjects?

提问人:Dilshan Prasad 提问时间:9/6/2023 更新时间:9/6/2023 访问量:55

问:

我们如何重构以下代码以删除使用 behaviorsubject 的链接,以便一个函数调用的失败不会影响使用其他函数调用数据的 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;
  })
JavaScript Angular TypeScript 异步 RXJS

评论

1赞 BizzyBob 9/6/2023
这可以在不使用主题的情况下进行简化。为什么要使用 BehaviorSubject?
0赞 Dilshan Prasad 9/6/2023
@BizzyBob我需要使用 behaviorSubjects,因为每个数据都是异步更新的。我们怎样才能简化它?

答:

1赞 maxime1992 9/6/2023 #1

以下是实现此目的的方法:

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
            ? of(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
  });

这将确保如果有任何失败,它不会为整个可观察对象出错。