Call a function every 10 seconds Angular2

2019-02-06 07:58发布

I'm trying to create a Timer that calls an API call every 10 seconds, I'm using setTimeOut but the thing is that it becomes an infinite loop, and even if I push to another page it keeps joining the if condition.

Example :

I call this on a method to start the 10 seconds API calls

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

And this is the onTimeOut() method...

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

I've heard about Debounce and rxjs/rs but I'm not familiar with them, could you give me some tips to do the same with that? Or if this way is more efficient go ahead and explain to me why it becomes to a loop.

The goal is when it joins the if and push the page, stop the timer.

4条回答
Anthone
2楼-- · 2019-02-06 08:25

Use observable.timer for your purpose in angular way.

 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");

  }
}
查看更多
该账号已被封号
3楼-- · 2019-02-06 08:33

Better use observables

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

to stop it use

this.sub.unsubscribe();

Make sure to import interval with

import 'rxjs/add/observable/interval';
查看更多
smile是对你的礼貌
4楼-- · 2019-02-06 08:33

There is nothing wrong with setTiimeout, It’s just a bug in your codes. This is indeed an infinite loop(recursive function without a base condition) as you don't have any base condition there.

So, setTimeout will keep on calling onTimeOut() after every 1 second as it does not know where to stop. Just use a base condition to finish the recursion when you switch to other 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);
    }

ngOnDestroy method will set the flag as false and the last call of the recursive function won't go inside the if block and as there is nothing to be executed after that, It will return back (previous state of it) and will clear it up from the stack, This process will be repeated till the stack is cleared up(same thing would happen to previous version of it which is now on the top of the stack and thus will clear up the stack one by one recursively).

查看更多
Bombasti
5楼-- · 2019-02-06 08:40

A better solution than setTimeout in an Angular app could be to use Observable. Observable have a method named timer that you can use this way (and there is a TimerObservable too but I never used it so I don't know if this is the same thing):

timer = Observable.timer(initialDelay, period);

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

I encourage you to use RxJS and Observable for your requests too, instead of promises, it seams more the Angular way to do things to me, and RxJS is a really powerful library.

RxJS Observable doc

查看更多
登录 后发表回答