admin管理员组

文章数量:1323330

I have an angular 6 strange problem.

I am using setTimeout and clearTimeout functions to start/cancel the timeout. However this sometimes works, and sometimes doesn't. Even if the user triggers an (click) event and the clearTimeout is run, sometimes it forces player to draw two cards.

Here is the code

//an event that says we must call uno 
this._hubService.mustCallUno.subscribe(() => {
      this.mustCallUno = true;
      this._interval = window.setInterval(() => {
        this.countdown -= 100;
      }, 100);
      this._timer = window.setTimeout(() => {
        if (this.mustCallUno) {
            this.drawCard(2);
            this.callUno();
        }
      }, 2000);
    });

// a function player calls from UI to call uno and not draw 2 cards
  callUno() {
    this.mustCallUno = false;
    window.clearTimeout(this._timer);
    window.clearInterval(this._interval);
    this.countdown = 2000;
  }

So even if the player calls callUno() function, the setTimeout is executed. Even worse, the code goes through the first if check inside the setTimeout if( this.mustCallUno) which by all means should be false since we just set it to false when we called callUno() function this.mustCallUno = false;.

I used setTimeout (returns NodeJS.Timer) before window.setTimeout and the result was the same.

I have an angular 6 strange problem.

I am using setTimeout and clearTimeout functions to start/cancel the timeout. However this sometimes works, and sometimes doesn't. Even if the user triggers an (click) event and the clearTimeout is run, sometimes it forces player to draw two cards.

Here is the code

//an event that says we must call uno 
this._hubService.mustCallUno.subscribe(() => {
      this.mustCallUno = true;
      this._interval = window.setInterval(() => {
        this.countdown -= 100;
      }, 100);
      this._timer = window.setTimeout(() => {
        if (this.mustCallUno) {
            this.drawCard(2);
            this.callUno();
        }
      }, 2000);
    });

// a function player calls from UI to call uno and not draw 2 cards
  callUno() {
    this.mustCallUno = false;
    window.clearTimeout(this._timer);
    window.clearInterval(this._interval);
    this.countdown = 2000;
  }

So even if the player calls callUno() function, the setTimeout is executed. Even worse, the code goes through the first if check inside the setTimeout if( this.mustCallUno) which by all means should be false since we just set it to false when we called callUno() function this.mustCallUno = false;.

I used setTimeout (returns NodeJS.Timer) before window.setTimeout and the result was the same.

Share edited Aug 9, 2019 at 11:42 frank91 asked Aug 9, 2019 at 11:30 frank91frank91 1311 gold badge1 silver badge10 bronze badges 8
  • 2 May I ask why aren't you using rxjs observables ? – Florian Commented Aug 9, 2019 at 11:51
  • @Florian i'm kinda new to all this angular and rxjs world. Can you post the solution with observable and link me to some useful "Getting Started" page? Many thanks – frank91 Commented Aug 9, 2019 at 12:00
  • can you share the full code! I can't really understand what you are intending to do here – Aravind Commented Aug 9, 2019 at 12:07
  • @tonymarkoc oki. I'll show you a stackblitz with rxjs solution and documentation page. – Florian Commented Aug 9, 2019 at 12:12
  • 1 @Aravind The rest of the code is really not relevant. We get an event through websocket that the player must call uno (first function I wrote above - subscribe), and then the user has 2 seconds to press the UNO button in the UI which will call callUno() function which was supposed to clear timeout, so that the player doesn't draw 2 cards. – frank91 Commented Aug 9, 2019 at 12:12
 |  Show 3 more ments

2 Answers 2

Reset to default 2

You're using angular6+, so I suggest you to use reactive programming library such as rxjs

I made you a small example here.

Check for the possibility where function in this._hubService.mustCallUno.subscribe is run twice or multiple times, usually initially which you might not be expecting. Put a logger in function passed to mustCallUno.subscribe and callUno.

In this case what might be happening is this._timer and this._interval will have a different reference while the old references they hold, were not cleared because callUno is not called or is called less number of times than the callback in subscribe.

本文标签: javascriptAngular 6 setTimeout and clearTimeout errorStack Overflow