【问题标题】:RxJS Observables nested subscriptions?RxJS Observables 嵌套订阅?
【发布时间】:2017-08-10 20:18:08
【问题描述】:

有什么方法可以简化如下代码示例? 我找不到合适的运营商.. 谁能举个简短的例子?

this.returnsObservable1(...)
  .subscribe(

    success => {

      this.returnsObservable2(...)
        .subscribe(

          success => {

            this.returnsObservable3(...)
              .subscribe(

                success => {
                   ...
                },

【问题讨论】:

  • 您可能正在寻找flatMapswitchMap 运算符。

标签: rxjs observable subscribe


【解决方案1】:

如 cmets 中所述,您正在寻找 flatMap 运算符。

您可以在以前的答案中找到更多详细信息:

您的示例应为:

this.returnsObservable1(...)
  .flatMap(success => this.returnsObservable2(...))
  .flatMap(success => this.returnsObservable3(...))
  .subscribe(success => {(...)}); 

【讨论】:

  • @Robin Dijkhof 所以在平面图中使用了一个返回 observable 的函数,.flatMap(success => this.returnsObservable2(...)) 然后this.returnsObservable2(...) 我不需要订阅它吗?
【解决方案2】:

之前回答了 RxJS 5,我在使用 6 时进入了这个页面。

如果您也是 6(我认为您现在应该是),您可以在 pipe 中使用 flatmap 作为 operator

修改@user3743222的示例代码:

this.returnsObservable1(...)
  .pipe(
    flatMap(success => this.returnsObservable2(...)),
    flatMap(success => this.returnsObservable3(...))
  )
  .subscribe(success => {(...)}); 

【讨论】:

  • 如果returnsObservable2 会返回一个可观察的数组,你能举个例子吗?
  • 现在 flatMap 被称为 mergeMap(重命名)。
【解决方案3】:

switchMap 运算符也很有用。 可以在此处找到一些描述 switchMap 与嵌套订阅相比有用性的示例:

  1. 嵌套订阅的情况

这个 codepen 提供了一个演示: https://codepen.io/anon/pen/zdXBvP?editors=1111

Rx.Observable
  .interval(5000)
  .subscribe((val) => {
    console.log("outer:", val);
    Rx.Observable
      .interval(1000)
      .subscribe((ival) => {
        console.log("inner:", val, ival); 
      });
  });
  1. switchMap 的情况

这个 codepen 提供了一个演示: https://codepen.io/anon/pen/xLeOZW?editors=1111

Rx.Observable
  .interval(5000)
  .switchMap((val) => {
    console.log("outer:", val);
    return Rx.Observable.interval(1000).map((ival) => [val, ival]);
  })
  .subscribe((val) => {
    console.log("inner:", val[0], val[1]);
  });

【讨论】:

  • 例子还不够,谢谢分享。
  • 我发现的一个通用模式是将所有“订阅”替换为“switchMap”,返回下一个内部 Observable。然后将最嵌套的“订阅”添加到链的末尾
【解决方案4】:

您基本上需要排序。 使用 RxJS concat,您可以这样做:

import { concat } from 'rxjs';
...

concat(
  this.returnsObservable1(...), 
  this.returnsObservable2(...), 
  this.returnsObservable3(...), 
  ...
)
.subscribe(success => {(...)});

如果你后续的 observables 需要知道之前的值,你可以使用 RxJS concatMap 操作符。

import { concatMap } from 'rxjs/operators';
...

this.returnsObservable1(...)
  .pipe(
    concatMap(result1 => this.returnsObservable2(...)),
    concatMap(result2 => this.returnsObservable3(...)),
    ...
  )
  .subscribe(success => {(...)});

连接:https://www.learnrxjs.io/learn-rxjs/operators/combination/concat

concatMap:https://www.learnrxjs.io/learn-rxjs/operators/transformation/concatmap

【讨论】:

    猜你喜欢
    • 2021-05-10
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多