It's much better for you to use new Date()
for each loop because the interval used on setInterval
will not be 100% constant.
new Date()
will be accurate regardless of setInterval
variances
Here's a snippet from an answer I gave a couple days ago. It explains the issue with using setInterval
with fixed-value incrementing (or decrementing).
Beware of creating timers that increment with a fixed value
In your code, you have
setTimeout(() => this.count--, 1000);
The intention is for you to decrement your count
property once every second, but this is not the behavior you will be guaranteed.
Check out this little script
var state = {now: Date.now()};
function delta(now) {
let delta = now - state.now;
state.now = now;
return delta;
}
setInterval(() => console.log(delta(Date.now())), 1000);
// Output
1002
1000
1004
1002
1002
1001
1002
1000
We used setInterval(fn, 1000)
but the actual interval varies a couple milliseconds each time.
The problem is exaggerated if you do things like switch your browser's focus to a different tab, open a new tab, etc. Look at these more sporadic numbers
1005 // close to 1000 ms
1005 // ...
1004 // a little variance here
1004 // ...
1834 // switched focus to previous browser tab
1231 // let timer tab run in background for a couple seconds
1082 // ...
1330 // ...
1240 // ...
2014 // switched back to timer tab
1044 // switched to previous tab
2461 // rapidly switched to many tabs below
1998 // ...
2000 // look at these numbers...
1992 // not even close to the 1000 ms that we set for the interval
2021 // ...
1989 // switched back to this tab
1040 // ...
1003 // numbers appear to stabilize while this tab is in focus
1004 // ...
1005 // ...
So, this means you can't rely upon your setTimeout
(or setInterval
) function getting run once per 1000
ms. count
will be decremented with much variance depending on a wide variety of factors.
To work around this, you need to use a delta. That means before each "tick" of your timer, you need to take a timestamp using Date.now
. On the next tick, take a new timestamp and subtract your previous timestamp from the new one. That is your delta
. Using this value, add it to the Timer's total ms
to get the precise number of milliseconds the timer has been running for.