一旦我将组件留在 Angular 中,就停止调用连续函数

Stop a continuous function being called once I leave the component in Angular

我正在使用 Angular 构建应用程序。作为其中的一部分,我每 1 分钟调用一次 API 以获取连续数据。我的代码看起来像。

ngOnInit() {
    this.getRealTimeData();
  }

  intervalId : any

  getRealTimeData() {
    this.getChillerApiData()
    clearInterval(this.intervalId);
    this.intervalId = setInterval(() => {
      this.getChillerApiData();
    }, 1000);
  }

  getChillerApiData() {
    this.api.getFirstChillerData()
      .subscribe((first_data:any) => {
        this.first_api_data = first_data;
        console.log(this.first_api_data)
        this.putPrimaryPumpData();
      });
  }

我每 1 分钟或我提到的任何时间间隔获取一次数据。但是发生的事情是,当我离开该组件并继续使用另一个组件时,我仍然看到 API 以指定的时间间隔定期进行的调用(我可以看到控制台日志)。我该如何阻止这种情况发生?我的意思是一旦我离开这个组件 API 调用也应该停止。

首先这里有很多错误。

您调用了订阅,但并未取消订阅。你想取消订阅,你想清除间隔。如果未清除订阅,它将不断获取信息并不断重复。因此每次触发订阅时都会调用 putPrimaryPumpData。可以同时结束多个运行。

做类似的事情:

let sub = this.api.getFirstChillerData()
  .subscribe((first_data:any) => {
    sub.unsubscribe();
    this.first_api_data = first_data;
    console.log(this.first_api_data)
    this.putPrimaryPumpData();
  });

现在这不会创建 1000 个循环中的 100 个。 其次,您可以像这样使用 ngOnDestroy:

ngOnDestroy() {
  clearInterval(this.intervalId);
}

正是针对这种情况 angular 提供了 OnDestroy 生命周期事件。 您可以在清除间隔后挂钩此事件。

像这样:

intervalId : any

ngOnDestory() {
 clearInterval(this.intervalId);
}

使用OnDestroy()生命周期钩子。

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

export class AppComponent implements OnInit, OnDestroy {
  private intervalId: any
  private chillerDataSubscription: Subscription;

  constructor() { }

  ngOnInit() {
    this.getRealTimeData();
  }

  getRealTimeData() {
    this.getChillerApiData()
    clearInterval(this.intervalId);
    this.intervalId = setInterval(() => {
      this.getChillerApiData();
    }, 1000);
  }

  getChillerApiData() {
    if (this.chillerDataSubscription) {
      this.chillerDataSubscription.unsubscribe();
    }
    this.chillerDataSubscription = this.api.getFirstChillerData()
      .subscribe((first_data:any) => {
        this.first_api_data = first_data;
        console.log(this.first_api_data)
        this.putPrimaryPumpData();
      });
  }

  ngOnDestroy() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
    }
    if (this.chillerDataSubscription) {
      this.chillerDataSubscription.unsubscribe();
    }
  }
}

有关生命周期挂钩的更多详细信息,请参阅 here

我假设您正在 api 服务中发出 HTTP 请求。在这种情况下,请注意 getChillerApiData() 函数中的 chillerDataSubscription。它确保在发出新请求之前取消订阅任何未完成的请求。它可以防止累积过多的请求。

您可以在 ngOnDestroy 中清理您的组件。当组件从 DOM.

中删除时,此函数由 Angular 调用

您可以清除 ngOnDestroy 中的间隔,但在您的情况下,您最好在 RxJS 中执行间隔,您现有的调用可以是其中的一部分。

// other imports here
import { interval } from 'rxjs';
import { takeUntil, switchMap } from 'rxjs/operators';

// @Component decorator here
export class MyComponent implements OnInit, OnDestroy {

  // TODO: add constructor

  private destroyed: Subject<void> = new Subject<void>();

  ngOnInit() {
    // create an rxjs interval every 1000ms
    // or you could use timer(0, 1000) to start immediately
    interval(1000).pipe(
      // stop the interval whenever this.destroyed is called
      takeUntil(this.destroyed),
      // now make the api request
      switchMap(() => this.api.getFirstChillerData())
    ).subscribe(data => {
      this.first_api_data = data;
      this.putPrimaryPumpData();
    });
  }

  ngOnDestroy() {
    // called when the component is removed from the DOM. 
    // cancel the interval and tidy up
    this.destroyed.next();
    this.destroyed.complete();
  }
}