【发布时间】:2018-02-22 01:29:43
【问题描述】:
我最近问了一个关于如果 switchMap 遇到错误会丢失订阅的问题:
Angular 4 losing subscription with router paramMap using switchMap
解决方案是返回一个空的 Observable,因为一旦 Observable 遇到错误,订阅就会被销毁。
我现在需要弄清楚如何使用相同的代码进行轮询,但在 API 返回数据后停止轮询 - 我相信返回这个空的 Observable 会导致我的轮询代码无法按预期工作。
当前代码没有轮询:
ngOnInit() {
this.subscription = this.route.paramMap
.switchMap( (params) => {
this.setChartDefaults();
return this.getForecastData(params.get('id'))
.do(null, (err) => {
this.errorText = err.statusText
this.loading = false;
})
.catch( () => { return Observable.empty() });
})
}
ngAfterViewInit() {
this.subscription.subscribe( (data) => {
// business logic
}
}
提议的代码有轮询:
ngOnInit() {
this.subscription = this.route.paramMap
.switchMap( (params) => {
return Observable
.interval(10000)
.startWith(0)
.flatMap( () => {
return this.getForecastData(params.get('id'))
})
.filter( (val) => {
return val.Interval != null
})
.take(1)
.map((forecast) => forecast)
.do(null, (err) => {
this.errorText = err.statusText
this.loading = false;
})
.catch( () => { return Observable.empty() });
})
}
ngAfterViewInit() {
this.subscription.subscribe( (data) => {
// business logic
}
}
- route.paramMap 上的 switchMap,这意味着任何以前的 Observable 都被取消了
- 返回间隔为 10 秒并立即启动的新 Observable
- flatMap HTTP 请求和轮询 Observables
- 过滤传入的数据,如果它具有 Interval 属性,则接受它并停止轮询
- map 返回订阅所需的新可观察对象
- 问题在于返回一个空的 observable 来处理原始问题
此代码始终采用第一个结果(使用 take(1))但是我的理解是,如果您首先过滤,您实际上可以只采用第一个有效的结果(在我的情况下有一个有效的响应)。
这是我目前的有限理解,我认为我的知识显然存在差距,因此我正在尝试更多地了解这些运算符和 Observable 的链接如何工作。
【问题讨论】:
-
所以它不起作用怎么办?或者这段代码应该做什么?您正在使用
take(1),因此Observable.interval始终只发出一项,然后链就完成了。 -
抱歉,已为问题添加了更多详细信息。
标签: javascript angular rxjs observable