web-dev-qa-db-fra.com

Appelle une fonction toutes les 10 secondes. Angular2

J'essaie de créer un Timer qui appelle un API call Toutes les 10 secondes. J'utilise setTimeOut mais le fait est que cela devient une boucle infinie, et même si I Appuyez sur une autre page, il ne cesse de rejoindre la condition if.

Exemple :

J'appelle cela sur une méthode pour démarrer les appels API de 10 secondes

setTimeout(() => {
    this.onTimeOut();
}, 1000);

Et voici la méthode onTimeOut() ...

onTimeOut() {
    this.ApiCall().then(
    success => {
    if(success ['ok'] == 0){
        this.navCtrl.Push(myPage);
    }
    },
    error => { console.log(error); });
}
setTimeout(() => {
    this.onTimeOut();
}, 1000);
}

J'ai entendu parler de Debounce et de rxjs/rs, Mais je ne les connais pas. Pouvez-vous me donner quelques conseils pour en faire autant? Ou si cette méthode est plus efficace, expliquez-moi pourquoi cela devient une boucle.

L'objectif est de rejoindre le if et de pousser la page, arrêter le chronomètre.

18
StuartDTO

Mieux utiliser les observables

this.sub = Observable.interval(10000)
    .subscribe((val) => { console.log('called'); });

pour l'empêcher d'utiliser

this.sub.unsubscribe();

Assurez-vous d'importer interval avec

import 'rxjs/add/observable/interval';
57
Günter Zöchbauer

Une meilleure solution que setTimeout dans une application Angular pourrait être d'utiliser Observable. Observable possède une méthode appelée timer que vous pouvez utiliser de cette façon (et il existe aussi une TimerObservable mais je ne l'ai jamais utilisée Je ne sais pas si c'est la même chose):

timer = Observable.timer(initialDelay, period);

timer.subscribe(tick => {
   // Your API call, which will be performed every period
});

Je vous encourage également à utiliser RxJS et Observable pour vos demandes également, au lieu de promesses, cela semble être la méthode Angular pour me faire quelque chose, et RxJS est une bibliothèque vraiment puissante.

RxJS Observable doc

6
Korbraan

Utilisation observable.timer pour votre usage de manière angular.

 export class CurrentRunsComponent implements OnInit, OnDestroy {
  private timer;


  ngOnInit() {
    this.timer = Observable.timer(10000);
    this.timer.subscribe((t) => this.onTimeOut());
  }
   onTimeOut() {
    this.ApiCall().then(
    success => {
    if(success ['ok'] == 0){
        this.navCtrl.Push(myPage);
    }
    },
    error => { console.log(error); });
}

   ngOnDestroy(){
    console.log("Destroy timer");

  }
}
2
Rohan Fating

SetTiimeout n’est pas faux, c’est juste un bug dans vos codes. Il s’agit bien d’une boucle infinie (fonction récursive sans condition de base) car vous n’y avez aucune condition de base.

Donc, setTimeout continuera d'appeler onTimeOut () toutes les secondes car il ne sait pas où s'arrêter. Utilisez simplement une condition de base pour terminer la récursion lorsque vous basculez vers d'autres pages.

 private flag: boolean;

 ngOnInit() {
        this.flag = true;
 }

 ngOnDestroy() {
        this.flag = false;
 }
 onTimeOut() {
        this.ApiCall().then(
        success => {
        if(success ['ok'] == 0){
            this.navCtrl.Push(myPage);
        }
        },
        error => { console.log(error); });
    }
     setTimeout(() => {
     if(this.flag){
        this.onTimeOut();
     }
    }, 1000);
    }

La méthode ngOnDestroy définira l'indicateur sur false et le dernier appel de la fonction récursive n'ira pas à l'intérieur du bloc if. Comme il n'y a rien à exécuter par la suite, il retournera (état précédent). et le nettoiera de la pile. Ce processus sera répété jusqu’à ce que la pile soit effacée (la même chose s’appliquerait à la version précédente de celui-ci qui se trouve maintenant au sommet de la pile et effacera ainsi la pile un par un de manière récursive. ).

1
Kuldeep Raz