javascript - 记忆游戏中的setTimeout
问题描述
我正在用我的网页上的 javascript 制作一个记忆游戏。我有 3 个标记为 1、2 和 3 的按钮,它们应该按一定的顺序变成绿色然后再变成白色。顺序是随机的,每回合加1。然后玩家应该以正确的顺序点击按钮。问题是,当我将按钮颜色更改为绿色时,不是每个按钮按正确的顺序变为绿色然后再次变为白色,而是按钮一次全部变为绿色。这是javascript逻辑:
function lightUp() {
var arrayOrder = gameOrder.split("");
for(let i = 0; i < arrayOrder.length; i++) {
document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "green";
setTimeout(function() {
document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "white";
}, 1000);
}
}
gameOrder
是一个数字顺序的字符串(例如“12331232123”)
我认为游戏无法正常工作是因为它的工作方式setTimeout
,我相信它会在后台暂停并允许for
循环继续运行而不是暂停整个功能一秒钟(这是我想要做的)。
我希望每个按钮在下一个按钮改变颜色之前打开然后关闭。因此,如果顺序是 1 2 3,我希望按钮 1 变为绿色,然后变为白色,然后按钮 2 变为绿色,然后变为白色,最后按钮 3 变为绿色,然后变为白色。
解决方案
正如 espacarello 所指出的,JS 不是同步的。您可以使函数异步并等待setTimeout
.
这是我用 JS “动画”事物的首选方式:
async function lightUp() {
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
for (const i of gameOrder.split('')) {
const el = document.getElementById(`but${i}`);
el.style.backgroundColor = 'green';
await sleep(1000);
el.style.backgroundColor = 'white';
}
}
这保持简单和优雅,不会用大量的回调、递归或嵌套setTimeout
的 s 弄乱你的代码。它仍然是一个功能。
编辑:重要的是要注意 IE 不支持 Promises 或箭头函数语法。请参阅其他两个答案以获得更广泛的支持。
推荐阅读
- typescript - 在标头中设置令牌时如何使用get方法使用httpClient
- angular - 如何正确地将数据从 httpClient.get 移动到我的本地变量
- c# - 如何使用c#将特定范围内的单元格从一个excel工作簿复制到另一个工作簿
- c# - 为什么我的未经授权的控制器不返回 401 ASP.Net Core?
- python - 模拟 Django 模型方法
- java - 创建元素时插入语法错误
- php - 访问解码后的 json 中的数组值
- doc2vec - 如何将 infer_vector 用于多个文档?
- asp.net - 注册 IUserStore
使用简单注射器时出错 - javascript - 如何限制数字输入文本框为小时格式 0-24