我有一个带有计时器的子组件,每2秒钟我将api调用发送到服务器。只要用户在页面上,即使他/她参加婚礼并使页面(父组件窗口)保持打开状态,我也需要进行此呼叫。
这是我组件中的一些代码:
=COUNT(FIND("0",D6),FIND("1",D6),FIND("2",D6),FIND("3",D6),FIND("4",D6),FIND("5",D6),FIND("6",D6),FIND("7",D6),FIND("8",D6),FIND("9",D6))
这是destroy方法:
this.myTimer = Observable.timer(1, 2000);
this.myTimer
.mergeMapTo(this.myService.doSomeWork(this.myId))
.subscribe((data) => {
this.myData = data;
}, (errRes)=>{
console.log(errRes);
});
我只需单击菜单上的其他组件,即可看到调用 到服务器仍在发生。 我什至尝试关闭窗口(Chrome浏览器中的标签页),但仍然存在对服务器的调用。
知道为什么不调用ngOnDestroy吗?
更新 我正在使用“ rxjs”:“ ^ 5.5.12”,
来自package.json:
ngOnDestroy(): void {
this.myTimer.complete();
}
答案 0 :(得分:3)
好吧,可观察的是异步模式。它们基于推送而非拉动策略,即当它们获得数据时,便将数据推送给订户。现在,您在使用它们时必须小心,因为即使组件损坏,它们也会继续推送数据。您需要明确取消订阅可观察的项目。 在ngOnDestroy()生命周期挂钩中,您也需要这段代码。
this.myTimer.unsubscribe()
就是这样,您将不会获得更多数据。另外,您可以使用takeWhile()或takeUntil()方法。看一看- https://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/
答案 1 :(得分:3)
嗯。您可以尝试使用RxJS的takeUntil运算符。
首先,您将takeUntil
和Subject
导入组件。
import { takeUntil, mergeMap } from 'rxjs/operators';
import { Subject } from 'rxjs/Subject'
下一步,
unsubscribe: Subject<void> = new Subject();
然后
this.myTimer
.pipe(
mergeMap(this.myService.doSomeWork(this.myId)),
takeUntil(this.unsubscribe)
).subscribe((data) => {
this.myData = data;
}, (errRes)=>{
console.log(errRes);
});
请注意,takeUntil
必须是pipe()
上的最后一个运算符,以防止任何可观察对象“泄漏”出去。
在您的ngOnDestroy上,
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}