Подождите, пока setTimeout завершится, прежде чем возвращать значение Javascript - PullRequest
0 голосов
/ 28 ноября 2018

Я делаю простую игру в кости и настроил функцию, которая будет случайным образом генерировать числа и отображать их очень быстро, чтобы имитировать вид броска кубика.У меня проблема в том, что я хочу дождаться завершения симуляции, прежде чем вернуть значение, но вместо этого значение возвращается сразу.Может кто-то указать мне верное направление?По сути, я хочу, чтобы rollDie () дождался завершения diceSimulation (), прежде чем продолжить.

function rollDie(){

     diceSimulation();
     var result = Math.floor(Math.random() * 6) + 1;
     document.getElementById("result").innerHTML = result;
     return result;

}

function diceSimulation(){
     for (var i = 0; i < 30; i++) {
         var random; 
         (function (i) {
             setTimeout(function () {
                 random = Math.floor(Math.random() * 6) + 1;
                 document.getElementById("result").innerHTML = random;
             }, 50*i);
         })(i);
     }
}

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Вы можете достичь ожидаемого результата, используя обратный вызов или обещание.Простой пример ниже показывает, как вы можете использовать обещания в качестве решения:

let diceSimulation = () => {
console.log("Dice simulation complete");
};
let rollDie = new Promise((resolve,reject)=> {
resolve("Roll die is completed");
})

rollDie.then((message)=> {
    console.log(message);

    diceSimulation();
},
(fail)=> {

})
0 голосов
/ 28 ноября 2018

Один из вариантов: diceSimulation возвращает Promise, которое разрешается через 50 * 31 мс, а для rollDie - await it:

async function rollDie(){

  await diceSimulation();
  var result = Math.floor(Math.random() * 6) + 1;
  document.getElementById("result").innerHTML = result;
  return result;

}

function diceSimulation(){
  return new Promise((resolve) => {
    for (var i = 0; i < 30; i++) {
      (function (i) {
        setTimeout(function () {
          const random = Math.floor(Math.random() * 6) + 1;
          document.getElementById("result").innerHTML = random;
        }, 50*i);
      })(i);
    }
    setTimeout(resolve, 1530);
  });
}

Обратите внимание, что вместо (function (i) { внутри цикла, вы можете рассмотреть возможность использования let вместо var, гораздо приятнее читать и отлаживать.(Использование var имеет слишком много проблем - лучше использовать вместо него const или let, когда это возможно.) Было бы также более элегантно выбрать result один раз внутри diceSimulation, а нечем на каждой итерации цикла, и если вы не намеренно вставляете разметку HTML, лучше назначить testContent, а не innerHTML:

const result = document.getElementById("result");
for (let i = 0; i < 30; i++) {
  setTimeout(() => {
    const random = Math.floor(Math.random() * 6) + 1;
    result.textContent = random;
  }, 50*i);
}

Демонстрационная версия:

async function rollDie() {

  await diceSimulation();
  var result = Math.floor(Math.random() * 6) + 1;
  document.getElementById("result").innerHTML = result;
  return result;

}

function diceSimulation() {
  return new Promise((resolve) => {
    const result = document.getElementById("result");
    for (let i = 0; i < 30; i++) {
      setTimeout(() => {
        const random = Math.floor(Math.random() * 6) + 1;
        result.textContent = random;
      }, 50 * i);
    }
    setTimeout(resolve, 1530);
  });
}

rollDie();
<div id="result"></div>
...