我在admin组件中设置了一个间隔来检查新消息。但是当我注销时,我注意到interval方法仍在运行。
setInterval(() => {
this.service.checkNew();
}, 300);
// Code
checkNew() {
this.http.get(this.basic.url + 'checknew/').subscribe((res) => {
if (res['data'].length) {
let sound = new Audio();
sound.src = this.basic.static += 'sounds/alert.wav';
sound.play();
for (let item of res['data']) {
if (this.contacts.length) {
this.getItem('contacts/' + item.id + '/').then((message) => {
this.contacts.unshift(<any>message);
});
}
this.messages += 1;
this.basic.fireAlert(item['name'] + ' Send message', 4);
}
}
});
}
检查图像中控制台的网络部分https://i.stack.imgur.com/18zpu.png
与订阅一样,这些回调在退出组件时不会被销毁。
所以你需要在创建interval时存储它的引用:
this.checkInterval = setInterval(() => {
this.service.checkNew();
}, 300);
并在ngOnDestroy
中添加clearInterval以在组件被销毁时销毁它:
ngOnDestroy() {
clearInterval(this.checkInterval);
}
使用setInterval进行轮询是一个非常糟糕的主意。setInterval
不关心之前的调用,如果由于某种原因您的服务器变慢,您将最终排队请求,直到服务器崩溃。我建议你使用RxJs
const fakeAsyncWork = (index) => of(index).pipe(delay(10 * index))
let index = 1;
defer(() => fakeAsyncWork(index))
.pipe(repeatWhen((res) => res.pipe(delay(100))))
.subscribe((res) => {
console.log(res + ' fake async took: ' + 10 * index + 'ms to perform');
index = index + 5;
});
这样你就可以确保每次调用之间的延迟被尊重。要发布订阅,您可以在ngOnDestroy
上调用取消订阅或使用此库https://github.com/ngneat/until-destroy