0
votes

I'm trying to create a countdown timer that will show accurate milliseconds once the timer reaches below 1 minutes (59 seconds or less) in Angular 4 for a sporting event clock, but I'm having trouble with the setInterval function. Here's the code:

JavaScript:

timer: number = 100;
intervalId: number = -1;

start() {
  this.intervalId = setInterval(() => {
    this.timeIt()
  }, 1000);   

  if (this.timer <= 0) {
    this.stop();
  }

}

stop() {
   clearInterval(this.intervalId);
   this.intervalId = -1;
}

startStop() {
  if(this.intervalId == -1) {
    this.start();
  }  else {
    this.stop();
  }
}

timeIt() {
 this.timer--;
 if (this.timer == 0) {
   clearInterval(this.intervalId);
 }
}

convertSeconds(s) {
  var minutes = Math.floor(s / 60);
  var seconds = (s % 60)
  var milliseconds = s;

  if (this.timer >= 60)
    return p5.prototype.nf(minutes, 1) + ':' + p5.prototype.nf(seconds, 2);
  else if (this.timer < 10)
    return p5.prototype.nf(seconds, 1) + '.';
  else 
    return p5.prototype.nf(seconds, 2) + '.';
}

HTML:

<h1>{{ convertSeconds(timer) }}</h1>
<button (click)="startStop()">Start/Stop</button>

I'm having trouble with the setInterval function, I know I can't count milliseconds if the parameter I'm using is 1000, but when I try using 1 or 10 as the parameter the code gets all buggy. As you can see the in the HTML code I'm calling the convertSeconds() function which renders the time on the page. Been stuck on this problem for a while now, please someone help!

1
setInterval is not trusted. Use new Date() would set timer accurately. - Rach Chen

1 Answers

0
votes

To help you understand why your code gets buggy, I suggest to read next post: http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/ It's not really possible to display precise milliseconds (like sporting events clock do) using setInterval. You might have different time between your interval functions, because they will be set on the next tick and amount of ticks will depend on the system performance and if there was UI-blocking operation or not. Think of 60 fps here. If we take 1000ms and divide it by 60 frames it will get you 16ms for each frame. That mean you'll need to manage to get reflow and repaint done in this timeframe to get everything run smoothly. You can read about them here: http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/ Also for more accuracy you probably need to calculate new Date().getTime() each time, so even if your setInterval fails to call next function on time, you still have correct time (at least). Let me know if you have any other questions, I ready to answer them in comments.