Завершение подфункции с помощью цикла setTimeout перед функцией - PullRequest
0 голосов
/ 02 мая 2018

Я боролся с проблемой синхронизации в своем коде уже несколько ночей и не могу найти правильное решение.

Описание кода Psuedo:

// прослушиватель событий на кнопке запускает бросок кубика при каждом нажатии

// вызов функции анимации // генерируем случайные значения x количество раз // отображать каждый результат с помощью setTimeout // запускаем код для определения окончательного значения "рассчитано" и отображения результатов

HTML:

<!DOCTYPE html>

<html lang="en">
  <meta charset="utf-8">
<head>
  <title>Make Cards</title>
</head>
<body>

  <p>Total:<span id="total"></span></p>
  <div id="contain">

  <div class="die"></div>
  <div class="die"></div>
  <div class="die"></div>
  <div class="die"></div>
  <div class="die"></div>
  <div class="die"></div>

    <br>

  <button id="rollBtn">Roll</button>
  <input type="number" value = "1" min="1" max="6" id = "numDice">

  </div>

</body>
</html>

Javascript:

var diceValue = ["&#9856", "&#9857", "&#9858", "&#9859", "&#9860", 
"&#9861"];
var dice = document.querySelectorAll(".die");
// select number of dice
var numDice = document.querySelector("#numDice");
// convert string to value
var newNumDice = Number(numDice.value);
var roll = document.querySelector("#rollBtn");
var total = document.querySelector("#total");


// make animation function
// call animation function


init();

function init(){
  displayDice();
  }
//THIS IS THE BUTTON LISTERNER
roll.addEventListener("click", function(){
//THIS SHOULD RUN BEFORE THE REST OF THE FUNCTION (BUT DOESN'T SEEM TO)
  animate();
  var subTotal = 0;
  for (var i = 0; i < newNumDice; i++){
    var value = generateRandomDice() 
    dice[i].innerHTML = diceValue[value];
    subTotal = subTotal + (value+1);
    total.innerHTML = subTotal;
  }      
  for (var i = 0; i < 6; i++){
    dice[i].style.color = "black";
  }
                      })


numDice.addEventListener("click", function(){
  total.innerHTML = "-";
   newNumDice = Number(numDice.value);
  resetDice();
  displayDice();
  // console.log(Number(numDice.value));
})

function resetDice(){
  for (var i = 0; i < diceValue.length; i++){
    dice[i].innerHTML = "";
  }
}

// only display chosen number of dice

function displayDice(){
  for (var i = 0; i < newNumDice; i++){
    dice[i].innerHTML = diceValue[i];
  }
}

function generateRandomDice(){
  var dieSide = Math.floor(Math.random() * 6);
  return dieSide;
}

//ATTEMPT AT WRITING CODE FOR ANIMATION
function animate(){
  for (var i = 0; i < 50000; i++){
  var ani = setTimeout(rolling, 650);
  }
  }

function rolling(){
                for (var i = 0; i < newNumDice; i++){
    var value = generateRandomDice() 
    dice[i].innerHTML = diceValue[value];
    dice[i].style.color = "grey";
}
}

Не уверен, что происходит, но мне кажется, что одушевленный (); код не запускается до тех пор, пока не завершится остальная часть eventListener. Любая помощь отличная, спасибо.

1 Ответ

0 голосов
/ 02 мая 2018

Проблема в том, что вы ожидаете завершения асинхронного кода, прежде чем выполнять синхронный код. Каждый раз, когда вы вызываете setTimeout, он сохраняет функцию для вызова, когда он готов к вызову (что составляет 650 мс от «сейчас»!).

Чтобы исправить, вы можете await, чтобы закончить анимацию. Вот как у меня это работает на вашем коде:

Изменить animate на:

function animate() {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < 50000; i++) {
      setTimeout(() => {
        rolling();

        if(i == 49999)
          resolve();
      }, 650);
    }
  });
}

и затем вы можете дождаться разрешения Обещания, изменив прослушиватель щелчков следующим образом:

roll.addEventListener("click", async function() {
  await animate();
  var subTotal = 0;
  for (var i = 0; i < newNumDice; i++) {
    var value = generateRandomDice();
    dice[i].innerHTML = diceValue[value];
    subTotal = subTotal + (value + 1);
    total.innerHTML = subTotal;
  }
  for (var i = 0; i < 6; i++) {
    dice[i].style.color = "black";
  }
});

Результат, показанный позже, был верным для меня.

Надеюсь, это поможет!

...