在 RxJs 6 中避免嵌套的 subcribe() 调用

Avoiding nested subcribe() calls in RxJs 6

有时我需要一个来自先前可观察值的值和 运行 另一个依赖于该值的函数等等。它进行嵌套的 subcribe() 调用,然后代码非常丑陋且难以管理。我这里有一个例子:

getObservableData().subcribe(next=>
    let dialogRef=this.dialog.open(EvalListComponent, {data: next})
    dialogRef.afterClosed().subscribe(next=>{
        let k=dialogRef.componentInstance.getAnotherObservableData()
            .subcribe( next=> doSomthing(next))
}))

什么样的解决方案才会出现这样的情况。我需要一些扁平结构。我知道有一个管道函数,可以将它与 rxjs 运算符一起使用。但是如何实现呢?

一般来说,我更喜欢在执行异步操作和监听变化时创建Subject

例如:
```

private dialogActionSubject: Subject<string>;

public onAlertActionBtnClicked(data): void {
    this.dialogActionSubject.next(data);
}

const subs = this.dialogActionSubject
    .pipe(
        distinctUntilChanged()
    )
   .subscribe(action => {});

```

我推荐这篇文章:learn flattening strategies

TLDR:使用地图运算符,例如:mergeMapswitchMapconcatMapexhaustMap.

All of them mostly work in the same manner —

  1. They map some value to an observable (you are the one in charge of returning an observable value from them, they just map it)

  2. They flatten the observable you return ( they just subscribe to it)

  3. They decide about what to do before / after they flatten (“Flattening Strategy”)

您唯一需要决定的是哪种策略对您的示例有用。看完文章你就明白了。

我建议查看 MergeMap and/or SwitchMap。 SwitchMap 可用于完成一个异步调用,确定它是否成功完成,然后使用该数据进行另一个异步调用。

return getObservableData()
.switchMap(next => {
    return let dialogRef = this.dialog.open(EvalListComponent, {data: next}
})
.catch(error => {
    return Observable.of(...)
}
.switchMap(x => {
        ...
})
.catch( ...and so on and so on...)