【问题标题】:How to implement several nested and interdependent subscriptions with RxJS operators?如何使用 RxJS 操作符实现多个嵌套且相互依赖的订阅?
【发布时间】:2019-04-15 09:00:48
【问题描述】:

我有嵌套订阅,我想使用合适的RxJS 运算符来摆脱它。我已经尝试过concatMapmergeMap,但很遗憾无法解决我的问题。

我有 3 个相互依赖的订阅,并在 forEach 循环中为当前循环的每个值触发一个新的 observable。为了更详细地说明这一点,这是我的示例代码:

this.subscriptionOne = this.serviceOne.getStreets().subscribe((streets) => {
  streets.forEach((street) => {
    this.subscriptionTwo = this.serviceTwo.getMetaData(street.id).subscribe((metaDatas) => {
      metaDatas.forEach((md) => {
        // do some stuff and then trigger another observable..
        this.subscriptionThree = this.serviceTwo.getStuff(md.id, md.type, md.name).subscribe((stuff) => {
          // do some other stuff
        });
      });
    });
  });
});

如何使用 RxJs 摆脱这种嵌套?

【问题讨论】:

    标签: angular typescript rxjs observable rxjs6


    【解决方案1】:
    let sub = this.serviceOne
      .getStreets()
      .pipe(
        mergeMap(streets => {
          return from(streets);
        }),
        mergeMap(street => {
          return this.serviceTwo.getMetaData(street.id);
        }),
        mergeMap(metaDatas => {
          return from(metaDatas);
        }),
        mergeMap(md => {
          return this.serviceTwo.getStuff(md.id, md.type, md.name);
        }),
        map(stuff => {
          // do your stuff
        })
      )
      .subscribe();
    

    metaDatas 在最后两个运算符中可用:

    let sub = this.serviceOne
      .getStreets()
      .pipe(
        mergeMap(streets => {
          return from(streets);
        }),
        mergeMap(street => {
          return this.serviceTwo.getMetaData(street.id);
        }),
        mergeMap(metaDatas => {
          return from(metaDatas).pipe(
            mergeMap(md => {
              return this.serviceTwo.getStuff(md.id, md.type, md.name);
            }),
            map(stuff => {
              // do your stuff
            })
          );
        })
      )
      .subscribe();
    

    【讨论】:

    • 所以没有必要再进行 foreach 研磨了?那么这可能是我的错误..我稍后会测试你的方法并给你一个反馈。谢谢!
    • 是的,你不再需要forEach了。
    • 是否还有一种方法可以合并最后两个 mergeMap,或者我仍然可以在 subscribe 函数中访问/迭代“metaDatas”吗?因为在最后一个 mergeMap 中调用 getStuff() 之后,我仍然需要来自“元数据”的一些属性来生成最终对象的选项。
    • 您可以将metaDatas保存在一个变量中,该变量属于包含整个订阅的方法,当然,您也可以将最后两个运算符包含在一个父运算符中。
    • 如果你想解开像streets这样的数组,你必须用from(streets)把它们变成Observables,或者你可以只返回一个数组,mergeMap将分别重新发出每个项目mergeMap(streets => streets) (好吧,或者改用mergeAll)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2020-10-17
    • 2020-02-29
    • 2020-08-18
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多