Search code examples
javascriptfunctionsettimeoutexecution

Prevent JavaScript function from running twice (setTimeout)


I have this function that runs for several seconds with the use of setTimeout. This function is ran when a button is clicked.

function complete() {
    var div = document.getElementById('log');
    setTimeout(function(){ div.innerHTML = div.innerHTML + intro[Math.floor(Math.random() * intro.length)] + "<br>"; }, 500);
    setTimeout(function(){ div.innerHTML = div.innerHTML + second[Math.floor(Math.random() * second.length)] + "<br>"; }, 2560);
    setTimeout(function(){ div.innerHTML = div.innerHTML + third[Math.floor(Math.random() * third.length)] + "<br>"; }, 4860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fourth[Math.floor(Math.random() * fourth.length)] + "<br>"; }, 7860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fifth[Math.floor(Math.random() * fifth.length)] + "<br>"; }, 9640);
}

However, if the user clicks the button multiple times, this function begins to excute multiple times as well. I have tried to prevent this from occuring by using the code below, however, it is not working.

var running;
function complete() {
    if (running == true) { alert('error'); }
    running = true;
    var div = document.getElementById('log');
    setTimeout(function(){ div.innerHTML = div.innerHTML + intro[Math.floor(Math.random() * intro.length)] + "<br>"; }, 500);
    setTimeout(function(){ div.innerHTML = div.innerHTML + second[Math.floor(Math.random() * second.length)] + "<br>"; }, 2560);
    setTimeout(function(){ div.innerHTML = div.innerHTML + third[Math.floor(Math.random() * third.length)] + "<br>"; }, 4860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fourth[Math.floor(Math.random() * fourth.length)] + "<br>"; }, 7860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fifth[Math.floor(Math.random() * fifth.length)] + "<br>"; }, 9640);
    running = false;
}

What approach should I take, or how can I fix my code so it can accomplish what I am trying to do?


Solution

  • Your running = false; should be inside timeout function, as timeout will execute asyncronically, the running = false; will execute before your timeout ends

    A simple example would be

    var running = false,
        div = document.getElementById('response'),
        limit = 5,
        current = 0;
    
    $('#trigger').click(function () {
        if (running === true) {
            alert('Error: The cycle was running. Aborting.');
            running = false;
            return false;
        }
        running = true;
        var end = setInterval(function () {
            if (current >= limit || running == false) {
                running = false;
                clearInterval(end);
            }
            div.innerHTML += 'Hello World<br />';
            current++;
        }, 500);
    
    });
    

    JSFiddle Example