I'm making a simple countdown timer that displays the seconds and setseconds left. When an user clicks a button the countdown should stop and some text should be displayed instead of the timer. Everything works fine on pc but if I use my phone with a worse cpu I sometimes get this unexpected behaviour: when the user clicks the button the text shows for a fraction of a second and then the timer keeps going on. I thought it was caused by the clearTimeout() method being called when the function was running and right before a new timeout would be called but this post proved me wrong. Do you have any idea what's causing this behaviour and how should I go about fixing it?
const finished = () => { // finished() is also called when user clicks a button
// show some thext on the screen
clearTimeout(timeout);
}
const start = document.timeline.currentTime! // Think of it as Date.now(); also returns a ms value; just slightly faster.
const end = start + 30000 // the countodwn takes 30 seconds
let timeout:any;
const frame = () => {
const elapsed = Math.floor(end - document.timeline.currentTime!)
if (elapsed <= 0) {
finished()
return
};
let secs: number | string = Math.floor(elapsed / 1000)
let setsecs: number | string = Math.floor((elapsed % 1000) * 0.1)
secs = secs < 10 ? "0" + secs : secs
setsecs = setsecs < 10 ? "0" + setsecs : setsecs
result.innerText = `Time left: ${secs}.${setsecs}`
timeout = setTimeout(() => requestAnimationFrame(frame), 15 - elapsed % 15) // raf is for optimisation and I'm substracting the timeout by the time that has already passed for drift minimisation
}
frame()
EDIT: I managed to recreate the slow behaviour on my phone with promises: Here's the code