javascript - 在函数之前使用 setTimeout 循环完成子函数
问题描述
几个晚上以来,我一直在努力解决我的代码中的时间问题,并且无法提出正确的解决方案。
伪代码说明:
//按钮上的事件监听器在每次单击时触发掷骰子
// 调用动画函数 // 生成随机值 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 = ["⚀", "⚁", "⚂", "⚃", "⚄",
"⚅"];
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 的其余部分完成之前,代码不会运行。任何帮助都很棒,谢谢。
解决方案
问题是您在执行同步代码之前正在等待异步代码完成。每次调用 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";
}
});
之后显示的结果对我来说是正确的。
希望有帮助!
推荐阅读
- javascript - Reactjs在keyup上获取事件键码
- python-3.x - Python没有从给定线程将预期输出打印到屏幕
- python - Python:如何将数据库中的输入拆分为二维数组
- r - 将反应值作为参数传递给绘图函数
- python - pyodbc 查询在 Spyder 中有效,但在 PyCharm 中无效
- python-3.x - ValueError:在 backtrader 中出现的日期超出月份的范围
- google-apps-script - 是否可以在 AppScript 中批量请求谷歌教室
- java - 如果用户尚未通过身份验证,如何处理对视图的访问?
- javascript - 为什么回调/捕获块没有被执行?
- android - 第一次尝试 Android Studio。模拟器无法启动 - Linux