Skip to content Skip to sidebar Skip to footer

How To Stop Other Code From Running Until Settimeout() Finishes Running?

I am making a simple memory card game. If you click on two cards in a row that are the same they stay open. If you click on two cards in a row that are not the same they both close

Solution 1:

You can't prevent JavaScript code to run while your setTimeout() is waiting. This is the essence of the JavaScript run-to-completion/event loop execution model.

In your case you should have an additional flag to not do anything during that time:

const cards = document.querySelectorAll('.container__small');
let hasFlippedCard = false;
let firstCard, secondCard;
let lockBoard = false;  // <<< use this flag

cards.forEach(function (card) {
  return card.addEventListener('click', flipCard);
});

functionflipCard(){
  if(lockBoard) return;  // <<< check flagthis.classList.add('flip');
  if(!hasFlippedCard){ 
    //first click
    hasFlippedCard = true;
    firstCard = this;
  }else {
    //second click
    hasFlippedCard = false;
    secondCard = this;
    lockBoard = true; // <<< set flagsetTimeout(function(){
      if(firstCard.dataset.framework !== secondCard.dataset.framework ){
        firstCard.classList.remove('flip');
        secondCard.classList.remove('flip');
      }
      lockBoard = false;  // <<< unset flag
    }, 1500);
  }
}

Solution 2:

function flipCard(){
  if (lockBoard) {
    return
  }
....

end in your setTimeout function

lockBoard = truesetTimeout(function(){
  ....
  lockBoard = false
}, 1500)

Solution 3:

Try something like this: disable the cards before the setTimeout function and re-enable them after the function executes.

document.querySelectorAll('.container__small').addAttribute("disabled",true);

setTimeout(function(){
      if(firstCard.dataset.framework !== secondCard.dataset.framework ){
        firstCard.classList.remove('flip');
        secondCard.classList.remove('flip');
      }

      document.querySelectorAll('.container__small').removeAttribute("disabled");
    }, 1500);

Solution 4:

Use a boolean flag to determine if the timeout is in progress and then don't execute your callback if it is true.

const cards = document.querySelectorAll('.container__small');
let cardIsFlipping = false;
let hasFlippedCard = false;
let firstCard, secondCard;
let lockBoard = false;

cards.forEach(function (card) {
  return card.addEventListener('click', flipCard);
});

functionflipCard(){
  if(cardIsFlipping) {
     return;
  }

  this.classList.add('flip');
  if(!hasFlippedCard){ 
    //first click
    hasFlippedCard = true;
    firstCard = this;
  }else {
    //second click
    hasFlippedCard = false;
    secondCard = this;
    cardIsFlipping = true;
    setTimeout(function(){ 
      if(firstCard.dataset.framework !== secondCard.dataset.framework ){
        firstCard.classList.remove('flip');
        secondCard.classList.remove('flip');
      }
      cardIsFlipping = false;
    }, 1500);
  }
}

Solution 5:

setTimeout returns a positive integer that identifies the timer created by setTimeout so if you have something like:

var myTimer = setTimeout(function(){
  console.log( 'executed' );
}, 1500);

You can use clearTimeout( timeoutId ) where timeoutId is the value of myTimer so something like clearTimeout( myTimer ) will cancel the execution of that timer if hasn't been executed.

So something like:

var myTimer = setTimeout(function(){
  console.log( 'executed' );
}, 1500);

if ( myTimerId ) {
    clearTimeout( myTimerId );
}

The code that is inside of the if block can be placed inside of an event listener like a click as the one above so you can cancel the timer when the event has been clicked again.

Post a Comment for "How To Stop Other Code From Running Until Settimeout() Finishes Running?"