有时候,我需要一个先前可观察到的值,并运行另一个依赖于该值的函数,依此类推。它进行嵌套的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运算符一起使用。但是如何实现呢?
答案 0 :(得分:3)
我推荐这篇文章:learn flattening strategies。
TLDR:使用地图操作符,例如:mergeMap
,switchMap
,concatMap
,exhaustMap
。
它们大多数都以相同的方式工作-
它们将一些值映射到可观察值(您是负责从它们返回可观察值的对象,他们只是将其映射)
它们展平了您返回的可观察物(他们只是订阅了它)
他们决定扁平化前后的操作(“平化策略”)
您只需决定哪种策略对您的示例有用。通过阅读文章,您可以轻松地弄清楚。
答案 1 :(得分:0)
通常,我更喜欢在执行异步操作和侦听更改时创建Subject
。
例如:
```
private dialogActionSubject: Subject<string>;
public onAlertActionBtnClicked(data): void {
this.dialogActionSubject.next(data);
}
const subs = this.dialogActionSubject
.pipe(
distinctUntilChanged()
)
.subscribe(action => {});
```
答案 2 :(得分:0)
我建议您查看MergeMap和/或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...)