在函数之前使用setTimeout循环完成子函数

时间:2018-05-01 21:03:12

标签: javascript settimeout

我已经在我的代码中解决了几个晚上的计时问题,并且无法提出正确的解决方案。

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";
}
}

不确定发生了什么,但在我看来,animate();在eventListener的其余部分完成之前,代码不会运行。任何帮助都很棒,谢谢。

1 个答案:

答案 0 :(得分:0)

问题是您在执行同步代码之前等待异步代码完成。每次调用setTimeout时,它都会存储函数,以便在它准备好被调用时调用(从现在开始是#650;!)。

要修复,您可以await完成动画。以下是我如何使用您的codepen:

animate更改为:

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

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

然后您可以通过将您的点击监听器更改为此来等待Promise解决:

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";
  }
});

之后显示的结果对我来说是正确的。

希望有所帮助!