对于我页面上的一个元素,我希望文本每十秒更改一次,并且要更改类。文本更改很容易,类更改也很容易,但我的for
循环出现问题,我觉得我错过了一些东西。
我想让for loop
在数组中选择一个随机派系,然后将其应用于该元素。对于我的测试,我一直在使用console.log
而不是DOM操作。
首先,我设置了我的数组:
var factions = ["Enforcers", "Reapers", "Ular Boys", "Roaches"];
然后,我想要一个变量,它是一个随机选择的数字,引用这个数组:
var x = factions[Math.floor(Math.random()*factions.length)];
由此,我希望能够在其他位置运行Math.floor
和Math.random
函数。
function reDefine() {
x = factions[Math.floor(Math.random()*factions.length)];
console.log(x);
}
最后,我希望for loop
能够运行200次(我已经选择了200次,因为它超出了用户留在网站上的时间),所以我告诉它计为200(i = 0; i < 200
)。之后,我想每次迭代,等待10秒,所以我有一个Timeout
函数,延迟为10000
(毫秒)。然后,代码到reDefine
,然后,在测试的情况下,console.log
x
变量的新定义。
function reChange() {
for (var i = 0; i < 200; i++) {
setTimeout(function() {
reDefine();
console.log("Chosen faction is now: " + x);
}, 10000);
}
}
而不是计数到1
(第一次迭代),等待10000
,然后重新定义x
,它重新定义x
两百次,然后将它们全部记录下来。
我在这里有什么特别的错误,可能还有Timeout
功能吗?
答案 0 :(得分:2)
这里有什么我特别错的,可能是Timeout功能吗?
是的!你正在安排一堆延期回调,但实际上并没有等到一个完成后安排下一个回调。
您可以通过以下简单方法解决此问题:
function reChange(currentIndex) {
setTimeout(function() {
reDefine();
console.log("Chosen faction is now: " + factions[currentIndex]);
// If we haven't gotten to the end of the list, queue up another one
var nextIndex = ++currentIndex;
if (nextIndex < factions.length) {
// Enqueue the next faction
reChange(nextIndex);
}
}, 10000);
}
请务必注意,对于function
的每次通话,没有超时的currentIndex
reChange
超过currentIndex
的值。也就是说,下一次调用不会在任何先前的超时中替换sleep
,因为基元(包括数字)是按值传递的。 closure
核心问题是你现在的执行情况如下:
而不是:
因为JS是单线程的(对于大多数意图和目的),Closure in JS can be a tricky thing.添加了一个稍后要执行的回调。在超时到期之前它不会setTimeout
,就像传统的{{1}}那样。