[英]Angular 4 RxJS polling with switchMap
I recently asked a question related to subscriptions being lost if switchMap encountered an error: 我最近问了一个问题,如果switchMap遇到错误,则与订阅丢失有关的问题:
Angular 4 losing subscription with router paramMap using switchMap Angular 4使用SwitchMap的路由器paramMap失去订阅
The solution was to return an empty Observable as once an Observable hits an error the subscription will be destroyed. 解决方案是返回一个空的Observable,因为一旦Observable遇到错误,订阅将被销毁。
I now need to figure out how to poll with the same code but stop polling once the API returns data - I believe returning this empty Observable is causing my polling code to not work as expected. 现在,我需要弄清楚如何使用相同的代码进行轮询,但是一旦API返回数据,就必须停止轮询-我相信返回此空的Observable会导致我的轮询代码无法正常工作。
Current code WITHOUT POLLING: 当前代码无查询:
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
}
}
Proposed code 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
}
}
This code is always taking the first result (with the use of take(1)) however it was my understanding that if you filter first you can pragmatically only take the first result that is valid (in my case has a valid response). 这段代码始终采用第一个结果(使用take(1)),但是据我的理解,如果您首先进行过滤,则可以务实地仅采用有效的第一个结果(在我的情况下具有有效的响应)。
This is my current, limited understanding and believe there are clearly gaps in my knowledge so I'm attempting to learn more about how chaining of these operators and Observables works. 这是我目前有限的理解,并认为我的知识显然存在不足,因此我试图更多地了解这些运算符和Observable的链接方式。
So after more research on how RxJS Observables function I found that I shouldn't be letting the error 'propagate' through the chain and effectively cancel my subscription. 因此,在对RxJS Observables的功能进行了更多研究之后,我发现我不应该让错误“传播”通过链并有效地取消我的订阅。 I also simplified my code: 我还简化了代码:
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
});
}
I'm think I could swap out the second switchMap operator with flatMap but I want to ensure the previous (outer) Observable is cancelled. 我认为我可以将第二个switchMap运算符与flatMap换出,但是我想确保取消先前的(外部)Observable。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.