Brick Yang
Brick Yang

Reputation: 5477

How to stop a self-called setTimeout() function?

I have a count down function. The function used setTimeout() to repeatedly call itself:

function countDownSendCode(timer) {
    if(timer >= 0) {
        document.querySelector('#send-code').setAttribute('disabled', true);
        document.querySelector('#send-code').innerHTML = timer + 's later resend';
        setTimeout(function() {
            countDownSendCode(timer - 1);
        }, 1000);
    } else {
        document.querySelector('#send-code').removeAttribute('disabled');
        document.querySelector('#send-code').innerHTML = 'Send';
    }
}

The document.querySelector('#send-code') is a button used to send code. When a user click the button, he cannot click it again until the count down over.

I added below function to the button's click event to call the count down:

function clickSendCode(ev) {
  ev.preventDefault();

  countDownSendCode(5);    // call the count down here

  handleAjaxRequest();
}

In some case, in the handleAjaxRequest(), I need to stop the count down and make the button available immediately.

I can call countDownSendCode(-1) to set the button available, but how can I clear the setTimeout()? Because it called by it self, I cannot get the timeID required by clearTimeout().

Upvotes: 3

Views: 1470

Answers (3)

Sufian Saory
Sufian Saory

Reputation: 892

function countDownSendCode(timer) { 
    if(timer >= 0) {
        document.querySelector('#send-code').setAttribute('disabled', true);
        document.querySelector('#send-code').innerHTML = timer + 's later resend';
       countDownSendCode._timer = setTimeout(function() {
            countDownSendCode(timer - 1);
        }, 1000);
    } 
    else {
        if('stop'===timer){
            clearTimeout(countDownSendCode._timer);     
        }
        document.querySelector('#send-code').removeAttribute('disabled');
        document.querySelector('#send-code').innerHTML = 'Send';
    }
}

modify the countDownSendCode function as above. call it with 'stop' string when you need the button to be available immediately.

Upvotes: 0

Alexander Bell
Alexander Bell

Reputation: 7918

You can achieve this functionality as shown in the following code snippet:

// global var serving as a handle to Timer
var _timer;

// call this function to start timer
function StartMyTimer() 
{
    _timer = setTimeout(function(){ alert("Hello, Timer is Running!"); }, 5000);
}

// call this function to stop timer
function StopMyTimer() 
{ 
  clearTimeout(_timer);
}

I would also suggest you to consider a pair of functions: setInterval() and clearInterval() which may simplify the coding of repetitive tasks.

Hope this will help.

Upvotes: 3

JRS
JRS

Reputation: 31

I'd suggest not recursively calling countDownSendCode(). Rather just set the timer to the correct number of seconds to begin with, then you can return a ref to the timer and pass it to the ajax handler.

Upvotes: 0

Related Questions