我正在开发一款西蒙游戏(你遵循颜色模式) . 它通过计算机第一次转弯和我的第一次转弯,但尝试在每个计算机选择之间执行setTimeout导致使用do while语句无限循环或者如果我使用for循环同时播放两个选项 . highlightDiv函数只在div上执行toggleClass,然后使用setTimeout将类重新切换回来 . audioStart函数使用switch语句来确定要播放的声音,然后使用setTimeout半秒来播放该声音 . 我认为增量上的这个setTimeout会让它们在增加之前有足够的时间发生,然后在computerChoice数组中执行下一个索引 . 如果这更容易,这是codepen:http://codepen.io/RawleJuglal/pen/pgRVKd
var computerChoice = ["red", "yellow"],index=0;
function computerPattern(cPattern, index){
console.log("Entered computer pattern function");
console.log("This is cPattern");
console.log(cPattern);
console.log("This is index: "+ index);
if(index !== cPattern.length)
{
highlightDiv(cPattern[index]);
audioStart(cPattern[index]);
index++;
computerPattern(cPattern, index);
}
else
{
index=0;
}
console.log("Leaving computerPattern function");
}
computerPattern(computerChoice, index);
3 回答
Javascript是单线程的,超时的概念意味着你将一个函数放在一个特殊的队列中,即在它们的时间到期时执行你的回调 . 现在,因为在你的代码中,i变量仅在超时函数中更新,该函数仅在3秒之后,这意味着循环体将一次又一次地运行直到满足3秒 .
在3秒内,javascript可以运行数千次迭代,每次迭代都会注册另一个超时,这意味着你的事件队列被炸毁,你的单线程将很难完成所有这些任务,直到我最终到达
cPattern.length
,如果有的话 .你的解决方案可能正在使用某种
setInterval
,它有一个你想要的回调函数,并且停止在每次递增的迭代变量上,让我们这样说:您正在递送一个名为
i
的变量,该变量在您传递给setTimeout的匿名函数委托中 . do-while循环所依赖的本地作用域变量i
永远不会更新 .根据您正在寻找的功能,您可以在变量
i
仍在范围内时递增它,然后使用闭包将其值的快照传递给setTimeout函数委托 .永远不会调用你的超时函数,因为你没有给它机会 . 只要您的代码正在运行(您的循环),浏览器就无法运行使用相同线程的预定脚本 . 您将不得不重新考虑代码 .