clearTimeout doesn't work when the timeout function is calling itself

I am using the code for accurate timer from this post: https://stackoverflow.com/a/29972322/17490329

but I modified it to be a countdown timer.

I want that when the countdown ends, it will stop, but using clearTimeout in my case doesn’t work:

let duration = 5; // seconds
countdownTimer(duration);

function countdownTimer (duration) {
    let interval = 1000; // milliseconds 
    let expected = Date.now() + interval;
    let timeoutHandler;

    setTimeout(step, interval);
    function step() {
        let dt = Date.now() - expected;
        if (dt > interval) {

        }
        console.log(duration);

        expected += interval;

        duration--;
        if (duration <= 0) {            
            clearTimeout(timeoutHandler); // doesn't stop the timer
        }
        timeoutHandler = setTimeout(step, Math.max(0, interval - dt)); // take into account drift
    }
}

Why?

>Solution :

let duration = 5; // seconds
countdownTimer(duration);

function countdownTimer (duration) {
    let interval = 1000; // milliseconds 
    let expected = Date.now() + interval;
    let timeoutHandler;

    setTimeout(step, interval);
    function step() {
        let dt = Date.now() - expected;
        if (dt > interval) {

        }
        console.log(duration);

        expected += interval;

        duration--;
        if (duration <= 0) {            
            clearTimeout(timeoutHandler); // doesn't stop the timer
            return; //don't forget to stop executing function
        }
        timeoutHandler = setTimeout(step, Math.max(0, interval - dt)); // take into account drift
    }
}

inside of "if" condition you miss "return" to stop executing fucntion

Leave a Reply