1
votes

Arrêter l'appel d'une fonction continue une fois que je quitte le composant dans Angular

Je crée une application avec Angular. Dans le cadre de celui-ci, je fais un appel API toutes les 1 min pour des données continues. Mon code ressemble à.

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

Je reçois des données toutes les 1 min ou quel que soit l'intervalle de temps que je mentionne. Mais ce qui se passe, c'est lorsque je quitte le composant et que je passe à un autre composant, je vois toujours des appels d'API effectués régulièrement à un intervalle spécifié (je peux voir les journaux de la console). Comment puis-je empêcher que cela se produise? Je veux dire une fois que je quitte ce composant, les appels d'API devraient également s'arrêter.


3 commentaires

Vous stockez l'ID d'intervalle, alors avez-vous essayé de l'utiliser pour l'effacer (voir angular.io/guide/lifecycle -hooks )? Vous pouvez également définir des intervalles "localement" à l'aide de la minuterie de RxJS.


Vous devez effacer l'intervalle dans le hook ngOnDestroy ().


Comment détruire / effacer l'intervalle dans ngOnDestroy ()?


4 Réponses :


1
votes

Tout d'abord, il y a tellement de choses qui ne vont pas ici.

Vous appelez un abonnement et il n'est pas désabonné. Vous souhaitez vous désabonner de l'abonnement et vous souhaitez effacer l'intervalle. Si l'abonnement n'est pas effacé, il continuera à recevoir des informations et à les répéter. Ainsi, putPrimaryPumpData sera appelé à chaque fois que l'abonnement est déclenché. Ce qui peut se terminer par plusieurs exécutions en même temps.

Faites quelque chose comme:

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

Maintenant, cela ne créera pas 100 des 1000 boucles. Deuxièmement, vous pouvez utiliser ngOnDestroy comme:

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


0 commentaires

1
votes

Exactement pour des cas comme cet angulaire fournit l'événement du cycle de vie OnDestroy. Vous pouvez vous connecter à cet événement en effaçant l'intervalle.

comme ceci:

intervalId : any

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


0 commentaires

1
votes

Utilisez OnDestroy () hook de cycle de vie.

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

Voir ici pour plus de détails sur les hooks de cycle de vie. P >

Je suppose que vous faites une requête HTTP dans votre service api. Dans ce cas, notez le chillerDataSubscription dans la fonction getChillerApiData (). Il s'assure que toutes les demandes en suspens sont désabonnées avant de faire une nouvelle demande. Cela empêche l'accumulation d'un trop grand nombre de requêtes.


0 commentaires

1
votes

Vous pouvez effacer votre composant dans ngOnDestroy . Cette fonction est appelée par Angular lorsque le composant est supprimé du DOM.

Vous pouvez effacer l'intervalle dans ngOnDestroy , mais dans votre cas, vous feriez probablement mieux d'effectuer l'intervalle dans RxJS, que votre l'appel existant peut faire partie de.

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


0 commentaires