对于循环迭代,一次发生而不是按延迟发生

时间:2016-06-08 15:56:33

标签: javascript arrays

对于我页面上的一个元素,我希望文本每十秒更改一次,并且要更改类。文本更改很容易,类更改也很容易,但我的for循环出现问题,我觉得我错过了一些东西。

我想让for loop在数组中选择一个随机派系,然后将其应用于该元素。对于我的测试,我一直在使用console.log而不是DOM操作。

首先,我设置了我的数组:

var factions = ["Enforcers", "Reapers", "Ular Boys", "Roaches"];

然后,我想要一个变量,它是一个随机选择的数字,引用这个数组:

var x = factions[Math.floor(Math.random()*factions.length)];

由此,我希望能够在其他位置运行Math.floorMath.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功能吗?

1 个答案:

答案 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

核心问题是你现在的执行情况如下:

    每个项目
    1. 等待
    2. 日志
  1. 而不是:

    1. 表示当前项目
      1. 等待
      2. 日志
      3. 重复
    2. 因为JS是单线程的(对于大多数意图和目的),Closure in JS can be a tricky thing.添加了一个稍后要执行的回调。在超时到期之前它不会setTimeout,就像传统的{{1}}那样。