7

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?

user3320550
  • 123
  • 1
  • 2
  • 9
  • Store the timeouts and clear them on subsequent clicks. – adeneo Apr 16 '14 at 20:18
  • 1
    I believe you'd want to set `running = false;` at the end of the execution _inside_ your timeouts. You could use a timeout, to run all other timeouts, and at the end of those timeoutes run `running = false;` may do the trick. So 'false' only gets set once in each loop AFTER all the elements run. You can then run `clearTimeout()` to stop the loops. – WASasquatch Apr 16 '14 at 20:18
  • You could use `clearTimeout` to stop them when you first execute `complete()`. If you want to clear them all at once, [refer to this post](http://stackoverflow.com/questions/8860188/is-there-a-way-to-clear-all-time-outs) for an example. – Goose Apr 16 '14 at 20:19
  • A simple solution would be to remove the event listener from the `button`. How to do it, depends on how have you attached the listener. Can you show, how the listener is attached? – Teemu Apr 16 '14 at 20:20
  • 1
    .. you should also `return` after the alert otherwise the rest of the function will still be executed – lostsource Apr 16 '14 at 20:21

3 Answers3

11

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

WASasquatch
  • 1,044
  • 3
  • 11
  • 19
juvian
  • 15,875
  • 2
  • 37
  • 38
0

Assuming you've used addEventListener to attach the click event to the button, you could remove the listener while timeouts are in progress:

function complete() {
    var div = document.getElementById('log'),
        button = this;
    this.removeEventListener('click', complete);
    setTimeout(function(){...});
                 :
    setTimeout(function(){...});
    // If you later want to make the button clickable again, just uncomment the line below:
    // setTimeout(function () {button.addEventListener('click', complete);}, 10000);
}
Teemu
  • 22,918
  • 7
  • 53
  • 106
0

for stop running timer you have to clear him

        var stopTimer;

        function someFunction() {
            stopTimer= setTimeout(function(){
                console.log("something done");
            }, 3000);
        }

        function stopFunction() {
            clearTimeout(stopTimer);
        }
Arthur Tsidkilov
  • 5,401
  • 2
  • 21
  • 18