Suo6613
Suo6613

Reputation: 441

Define a timer in JavaScript

I have a function in JavaScript. I use setInterval in order to control my function. I also have another logic for controlling my function. I have a counter which is increased once one condition happens and is decreased when another condition happens. Now, sometimes the second condition does not happen and hence my function won't be resume anymore. (I pause my function when my first condition happen). Therefore, I want to wait at most 30 seconds for the second condition. If it does not happen, then I want to resume my function anyway. I have following code, but it does not work as I expect it. What happens is that it resume my function every 30 seconds. Then, it may be resumed while it should wait. Can someone let me know what is the problem with my code?

Please note that, the value for the counter may increase to more than 20. I mean the first and second condition may occur more than once.

function main() 
{
    // body
}

function increaseCounter()
{
    counter += 1;

    clearInterval(controller);
    controlSecond = setInterval(function(){
        counterSeconds += 1;
        if (counterSeconds == 30)
        {
            counterSeconds = 0;

            controller = setInterval(main, 100);
            clearInterval(controlSecond);
        }
    }, 1000);
}

function decreaseCounter()
{
    counter -= 1;

    if (counter == 0)
    {
        counterSeconds = 0;
        clearInterval(controlSecond);

        controller = setInterval(main, 100);
    }
}

Upvotes: 0

Views: 136

Answers (2)

Wio
Wio

Reputation: 1251

Consider what happens if you call increaseCounter twice in a row.

On the first execution it will create interval A and assign it to controlSecond.

On the second execution it will create interval B and assign it to controlSecond, while interval A continues to fire off indefinitely. You won't stop it with clearInterval(controlSecond) because controlSecond no longer references interval A.

The problem is that you continue to set controlSecond and controller to a new interval without clearing them first. That results in the intervals being leaked with no way of clearing them. It's sort of like a memory leak where you have dynamically allocated memory but nothing pointed at it, but instead of renegade memory you have renegade intervals.

One way to prevent this is to make sure you always clear your interval before setting it.

I would also recommend that you implement controlSecond with a setTimeout because that is designed for tasks which only happen once.

Upvotes: 2

mbeloshitsky
mbeloshitsky

Reputation: 357

Why not

var counter = 0
var timeout = null

function main () {
    clearTimeout(timeout);
    timeout = null;
}

function increaseCounter () {
    counter++;
    if (!timeout)
        timeout = setTimeout(main, 30*1000);
}

function decreaseCounter() {
    counter--;
    if (counter === 0) 
        main();
}

Upvotes: 0

Related Questions