Ankit
Ankit

Reputation: 350

I am getting multiple instances of setInterval, when i run same function multiple time?

  
let output = document.getElementById('output');
function startGame(){
  let timerStart = 6;
  let countdown = setInterval(() => {
    timerStart--;
    if(timerStart === 0){
      clearInterval(countdown);
    }
    console.log(timerStart);
    output.innerHTML = timerStart;
    timer.innerHTML = timerStart;
  }, 1000);
}
<button onclick="startGame()">Start Game</button>
          
<p id='output'>output here</p>

Problem
When i click start game once it works just fine.
output: 5, 4,3,2,1
But when i click start game more then once, I get more then one timer running too like
output: 5, 4, 5,3, 4, 2, 3, 1, 2..etc Help me please...

Upvotes: 2

Views: 467

Answers (6)

Olivier Boiss&#233;
Olivier Boiss&#233;

Reputation: 18153

One possible solution is to clear the interval at the begining of the startGame function :

const output = document.getElementById('output');
let intervalId;    

function displayCounter(counter) {
  output.innerHTML = counter;
  timer.innerHTML = counter;
}

function startGame(){
  clearInterval(intervalId);
  let counter = 5;
  displayCounter(counter);

  intervalId = setInterval(() => {
    if(--counter === 0){
      clearInterval(intervalId);
    }
    console.log(counter);
    displayCounter(counter);
  }, 1000);
}

Another solution is to prevent the user to recreate multiple intervals

function startGame(){
  if(intervalId) {
    return;
  }

  let counter = 5;
  displayCounter(counter);
  ...

Upvotes: 1

Amardeep Bhowmick
Amardeep Bhowmick

Reputation: 16908

You need to check if the timer has been started already, if it is do not run the function. This can be done by using the countdown variable which will hold the timer id. If the id is populated then do not run the function again unless it reaches 0 and is cleared:

const startGame = (function(){
    let countdown = null;
    let output = document.getElementById('output');
    function startGame(){
      let timerStart = 6;
      if(countdown){ return; }
      countdown = setInterval(() => {
          timerStart--;
          if(timerStart === 0){
            clearInterval(countdown);
            countdown = null;
          }
          output.innerHTML = timerStart;
      }, 1000);
    }
    return startGame;
})();
<button onclick="startGame()">Start Game</button>
          
<p id='output'>output here</p>

Upvotes: 0

Chivenh
Chivenh

Reputation: 114

The truly problem is what you wish happen when you click the button more than once. If you want do nothing when click the button second time after the game was started. Maybe you do some change like these.

let output = document.getElementById('output');
let started=false;
function startGame(){
if(started)return;
  let timerStart = 6;
  let countdown = setInterval(() => {
    timerStart--;
    if(timerStart === 0){
      clearInterval(countdown);
started=false;
    }
    console.log(timerStart);
    output.innerHTML = timerStart;
    timer.innerHTML = timerStart;
  }, 1000);
started=true;
}

Upvotes: 0

Rowan Berry
Rowan Berry

Reputation: 211

because your not storing the value of countdown anywhere, the system requires a reference to the interval to clear it. outside of your function you should keep a list (or something) which contains each countdown variable

Upvotes: 0

Kryštof Řeh&#225;ček
Kryštof Řeh&#225;ček

Reputation: 2483

You should remember the previously started interval and then stopping it if it is already running like so

let countdown = null;
let output = document.getElementById('output');
function startGame(){
  let timerStart = 6;
  if (countdown) clearInterval(countdown);
  countdown = setInterval(() => {
    timerStart--;
    if(timerStart === 0){
      clearInterval(countdown);
    }
    console.log(timerStart);
    output.innerHTML = timerStart;
    timer.innerHTML = timerStart;
  }, 1000);
}

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371019

The interval ID should be persistent (in the outer scope), so that on a subsequent call of startGame, you can call clearInterval with it before going onto the rest of the code:

let output = document.getElementById('output');
let intervalId;
function startGame(){
  // Clear the past interval, if there is one:
  clearInterval(intervalId);

  let timerStart = 6;
  intervalId = setInterval(() => {
    timerStart--;
    if(timerStart === 0){
      clearInterval(intervalId);
    }
    console.log(timerStart);
    output.innerHTML = timerStart;
    timer.innerHTML = timerStart;
  }, 1000);
}

Upvotes: 2

Related Questions