我有一个角度组件,我定期从服务请求值:
setInterval(() => {
this.updateValues();
}, 1000);
updateValues(): void {
if (this.isValuesUpdateRunning === false) {
this.isValuesUpdateRunning = true;
this.apiService.getCurrentValues().subscribe((data: any) => {
if (data != null) {
this.currentValues = data;
this.isValuesUpdateRunning = false;
}
});
}
}
我很确定我应该在某个地方取消订阅该服务,因为我确实通过这样做打开了很多订阅。我在考虑使用异步管道,但是我需要设置“isValueUpdateR不”变量,如果我只是在模板中使用异步,这是不可能的。
此外,在Angular提供的“onDestroy”方法中取消订阅也没有帮助,因为据我所知,这个方法只有在我离开页面时才会被调用。但是我需要更频繁地关闭我的订阅,以防止保持数千个订阅打开。
我还尝试在设置值后立即关闭订阅,但在我的视图中没有任何值:
updateValues(): void {
if (this.isValuesUpdateRunning === false) {
this.isValuesUpdateRunning = true;
const sub = this.apiService.getCurrentValues().subscribe((data: any) => {
if (data != null) {
this.currentValues = data;
this.isValuesUpdateRunning = false;
}
});
// closing the subscription right here:
sub.unsubscribe();
}
}
你能帮忙吗?我没有主意了。
获得响应后,您可以关闭订阅,如下所示。另请注意,如果您从getCurrentValue()调用AJAXAPI,HTTPContable是自动关闭的,您不需要关闭订阅,因为一旦您获得超文本传输协议,响应订阅将由角HTTP客户端完成。
updateValues(): void {
if (this.isValuesUpdateRunning === false) {
this.isValuesUpdateRunning = true;
const sub = this.apiService.getCurrentValues().subscribe((data: any) => {
if (data != null) {
this.currentValues = data;
this.isValuesUpdateRunning = false;
}
// closing the subscription right here:
sub.unsubscribe();
}, error => { sub.unsubscribe});
}
}
假设您在模板中呈现当前值
,我建议使用异步管道。
根据isValuesUpdateRruning
逻辑,您可以使用在一个RxJS间隔中替换setTimeout
我在下面放了一个演示——我强烈建议学习模拟api服务并自己尝试这些东西。
const currentValues$ = interval(1000)
.pipe(
tap(i => console.log(`timer::${i}`)),
exhaustMap(i => apiService.getCurrentValues(i)), // ignores new values until api returns
tap(apiData => console.log(`api::${apiData}`)),
filter(data => !!data) // filter for truthy values
takeUntil(stopClick$), // or this.destroyed$ component logic
)
(这假设模板中使用异步管道,例如{{当前值$|async|json}}
)
更新-最好把采取直到最后!
AftustMap-忽略新发出的值,直到当前可观察完成(角超文本传输协议请求自动完成)
如果使用角度超文本传输协议客户端,您不需要取消订阅@Kurt Hamilton提到的服务。您需要停止创建订阅的设置间隔。
使用rxjs运算符的示例。
interval(1000)
.pipe(
takeWhile(() => this.isValuesUpdateRunning), // call subscription until the condition is false
switchMap(() => this.apiService.getCurrentValues()),
filter(Boolean), // check if response is not null
tap(resp => { this.data = resp; this.isValuesUpdateRunning = false; }),
// handle errors