繁体   English   中英

如何使用 MergeMap 或 FlatMap 或使用 rxJs-operators 的一些更好的方法编写以下代码?

[英]How to write below code using MergeMap or FlatMap or some better way with rxJs-operators?

我有两个可观察的管道。 我需要一个接一个地运行并比较两个值是否相等。 我尝试了下面的代码。这应该可以工作,当第一个可观察值发出时,它应该去取第二个 obserbla 值,并且应该首先返回值。我需要一些专家帮助,以更好的方式重新编写此代码。

   this.selectedUnitDetailModel$.pipe(shareReplayUntil(this.destroySub)).subscribe(
          (res: UnitDetail) =>{
              if(res.unitTwo){
                this.appStore.select(selectUnit).
                pipe(shareReplayUntil(this.destroySub)).subscribe(
                  (unitId: string) => {
                    if(unitId ===  res.unitTwo){
                      this.sameUnit = true;
                    }else{
                      this.sameUnit = false;
                    }
                  });
              }
          }
       );
this.selectedUnitDetailModel$.pipe(shareReplayUntil(this.destroySub),mergeMap(
          (res: UnitDetail) =>{
              if(res.unitTwo){
               return this.appStore.select(selectUnit).
                pipe(shareReplayUntil(this.destroySub),map(
                  (unitId: string) =>  unitId ===  res.unitTwo);
              }
          }
       ).subscribe({
        next: (sameUnit: boolean) => {
           //do something 
        }
       });

您不需要更高阶的运算符,因为可观察对象this.selectedUnitDetailModel$this.appStore.select(selectUnit)是相互独立的。 相反,您可以使用诸如forkJoincombineLatestzip类的函数来并行获取来自它们的通知。

你可以在这里找到这些函数的不同之

尝试以下

forkJoin(
  this.selectedUnitDetailModel$.pipe(take(1)),      // <-- complete on first emission
  this.appStore.select(selectUnit).pipe(take(1))    // <-- complete on first emission
).subscribe(
  ([res, unitId]) => this.sameUnit = res.unitTwo === unitId,
  (error) => console.log(error)                     // <-- handle error
);

forkJoin仅在源 observable 完成时发出,所以我已经take(1)到每个 observable 中。 forkJoin现在将在每个 observable 和 complete 的第一次发射时发射。 所以你的shareReplayUntil(this.destroySub)的需要被减轻了。

但是,如果您需要保持来自 observable 的发射流打开,您可以使用combineLatestzip代替。 在这种情况下,您可以将take(1)替换为您的“shareReplayUntil(this.destroySub)”。

更新: this.selectedUnitDetailModel$ observable 的连续流

就像我之前说的,您可以使用combineLatest而不是forkJoin来启用连续的数据流。

尝试以下

import { Subject, combineLatest } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

combineLatest(
  this.selectedUnitDetailModel$,
  this.appStore.select(selectUnit)
).pipe(
  takeUntil(this.destroySub)         // <-- replaced with `takeUntil` operator
).subscribe(
  ([res, unitId]) => this.sameUnit = res.unitTwo === unitId,
  (error) => console.log(error)                     // <-- handle error
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM