如何在Angular 5中正确实现ngOnDestroy()?

时间:2019-06-19 16:52:33

标签: angular rxjs observable

我有一个带有计时器的子组件,每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();
  }

2 个答案:

答案 0 :(得分:3)

好吧,可观察的是异步模式。它们基于推送而非拉动策略,即当它们获得数据时,便将数据推送给订户。现在,您在使用它们时必须小心,因为即使组件损坏,它们也会继续推送数据。您需要明确取消订阅可观察的项目。 在ngOnDestroy()生命周期挂钩中,您也需要这段代码。

this.myTimer.unsubscribe()

就是这样,您将不会获得更多数据。另外,您可以使用takeWhile()或takeUntil()方法。看一看- https://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/

答案 1 :(得分:3)

嗯。您可以尝试使用RxJS的takeUntil运算符。

首先,您将takeUntilSubject导入组件。

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();
}