RxJS可观察对象嵌套订阅?

44

如何简化以下代码示例?我找不到合适的运算符。有人能给一个简短的例子吗?

this.returnsObservable1(...)
  .subscribe(

    success => {

      this.returnsObservable2(...)
        .subscribe(

          success => {

            this.returnsObservable3(...)
              .subscribe(

                success => {
                   ...
                },

2
你可能正在寻找 flatMapswitchMap 操作符。 - Yaroslav Admin
4个回答

42

正如评论中所提到的,您正在寻找flatMap运算符。

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

您的示例将会是:

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

2
@Robin Dijkhof 在 flatMap 中使用返回 observable 的函数,例如: .flatMap(success => this.returnsObservable2(...)) 那么 this.returnsObservable2(...) 我需要订阅它吗? - Vikas Kalapur
1
flatMap现在被称为mergeMap。 - Michael Artman

32

之前我回答了一个关于 RxJS 5 的问题,在使用 RxJS 6 时访问到了这个页面。

如果你也在使用 RxJS 6(我认为你现在应该是),你可以在 pipe 中使用 flatmap 作为一个 操作符

修改了 @user3743222 的示例代码:

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

2
如果returnsObservable2返回一个可观察的数组,你能给出一个例子吗? - Paul Strupeikis
4
现在flatMap被称为mergeMap(更名)。 - Ε Г И І И О

10

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]);
  });

例子不一定足够,但感谢分享。 - spakmad
我发现一般的模式是用“switchMap”替换所有“subscribes”,并返回下一个内部Observable。然后将最嵌套的“subscribe”添加到链的末尾。 - reggaeguitar
对于嵌套的订阅,switchMap 是最佳方法。 - epinal

1
你基本上需要排序。 使用 RxJS 的 concat,你可以这样做:
import { concat } from 'rxjs';
...

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

如果您的后续可观察对象需要知道先前的值,则可以使用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

连接映射操作符:https://www.learnrxjs.io/learn-rxjs/operators/transformation/concatmap


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接