Instead of using a value that you increment/decrement when a callback is called, you should calculate when your countdown should finish. Then compare the current time against this target.
const MILLISECOND = 1;
const SECOND = 1000*MILLISECOND;
const MINUTE = 60*SECOND;
const finishAt = Date.now() + 1*MINUTE;
const intervalID = setInterval(() => {
const now = Date.now();
if (now < finishAt) {
// code that is executed at a 1 second interval (if the browser is active)
const msToGo = finishAt - now;
const secToGo = Math.floor(msToGo / SECOND);
console.log(secToGo);
} else {
clearInterval(intervalID);
// code to be executed when your timer finishes
console.log("done");
}
}, 1*SECOND);
const MILLISECOND = 1;
const SECOND = 1000*MILLISECOND;
const MINUTE = 60*SECOND;
const finishAt = Date.now() + 10*SECOND;
const intervalID = setInterval(() => {
const now = Date.now();
if (now < finishAt) {
// code that is executed at a 1 second interval (if the browser is active)
const msToGo = finishAt - now;
const secToGo = Math.floor(msToGo / SECOND);
console.log(secToGo);
} else {
clearInterval(intervalID);
// code to be executed when your timer finishes
console.log("done");
}
}, 1*SECOND);
Another option would be to create 2 callbacks. One that has a 1 second interval that executes some code at a specific interval. The other callback is a timeout that stops the interval.
const duration = 1*MINUTE;
const finishAt = Date.now() + duration;
const intervalID = setInterval(() => {
// code that is executed at a 1 second interval (if the browser is active)
const msToGo = finishAt - Date.now();
const secToGo = Math.floor(msToGo / SECOND);
console.log(secToGo);
}, 1*SECOND);
setTimeout(() => {
clearInterval(intervalID);
// code to be executed when your timer finishes
console.log("done");
}, duration);
const MILLISECOND = 1;
const SECOND = 1000*MILLISECOND;
const MINUTE = 60*SECOND;
const duration = 10*SECOND;
const finishAt = Date.now() + duration;
const intervalID = setInterval(() => {
// code that is executed at a 1 second interval (if the browser is active)
const msToGo = finishAt - Date.now();
const secToGo = Math.floor(msToGo / SECOND);
console.log(secToGo);
}, 1*SECOND);
setTimeout(() => {
clearInterval(intervalID);
// code to be executed when your timer finishes
console.log("done");
}, duration);
This second solution might drop an interval if the setTimeout()
callback is executed before the final setInterval()
tick. But in most scenarios this should not be an issue.