我最近问了一个与订阅丢失有关的问题,如果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
}
}
建议代码 WITH POLLING:
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
}
}
这段代码总是取第一个结果(使用take(1))然而我的理解是,如果你先过滤,你可以实际上只取第一个有效的结果(在我的情况下有一个有效的响应) )。
这是我当前的,有限的理解,并且相信我的知识中存在明显的差距,所以我试图更多地了解这些运算符和Observables的链接是如何工作的。
答案 0 :(得分:2)
因此,在对RxJS Observables如何运作进行更多研究之后,我发现我不应该让错误“传播”到链中并有效地取消我的订阅。我还简化了我的代码:
public getForecastData(forecastId) : Observable<any> {
return this.http
.get<any>('/api/forecasts/' + forecastId)
.map( res => res)
.catch( () => Observable.empty());
}
ngOnInit() {
let $pollObservable = Observable
.interval(8000)
.startWith(0);
this.subscription = this.route.paramMap
.switchMap( (params) =>
$pollObservable
.switchMap( () => {
this.setChartDefaults();
return this.getForecastData(params.get('id'))
})
.filter( (val) => {
return val.Interval != null
})
.take(1)
.map( forecast => forecast)
)
}
ngAfterViewInit() {
this.subscription.subscribe( (data) => {
// business logic
});
}
我想我可以用flatMap换掉第二个switchMap运算符,但我想确保取消之前的(外部)Observable。