如何在for循环中使用setInterval函数

时间:2011-10-13 03:19:05

标签: javascript for-loop closures setinterval

我正在尝试运行多个计时器给定一个变量列表。代码看起来像这样:

var list = Array(...);

for(var x in list){
    setInterval(function(){
        list[x] += 10;
        console.log(x + "=>" + list[x] + "\n");
    }, 5 * 1000);
}

上述代码的问题在于,更新的唯一值是列表末尾的项目,乘以列表中的项目数。

任何人都可以提供解决方案和一些解释,所以我知道它为什么会这样表现?

6 个答案:

答案 0 :(得分:38)

所以,有一些事情:

  1. 最重要的是,您传递给setInterval()的回调函数维护对x的引用,而不是x的快照值,因为它在每次特定迭代期间都存在。因此,当循环中更改x时,它也会在每个回调函数中更新。
  2. 此外,for...in用于枚举对象属性,并且在数组上使用时可以behave unexpectedly
  3. 更重要的是,我怀疑你真的想要setTimeout()而不是setInterval()
  4. 您可以通过向setTimout()提供其他参数来将参数传递给回调函数:

    var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

    以下是一个例子:

    var list = [1,2,3,4];
    
    for (var x = 0, ln = list.length; x < ln; x++) {
      setTimeout(function(y) {    
        console.log("%d => %d", y, list[y] += 10);
      }, x * 500, x); // we're passing x
    }

    幸运的是,数字通过值传递而不是参考。

答案 1 :(得分:38)

var list = [1, 2, 3, 4, 5];

for (var i = 0, len = list.length; i < len; i += 1) {
    (function(i) {
        setInterval(function() {
            list[i] += 10;
            console.log(i + "=>" + list[i] + "\n");
        }, 5000)
    })(i);
}

以下是工作代码:

var list = [1, 2, 3, 4, 5];

for (var i = 0, len = list.length; i < len; i += 1) {
    (function(i) {
        setInterval(function() {
            list[i] += 10;
            console.log(i + "=>" + list[i] + "\n");
        }, 5000)
    })(i);
}

此处索引i存储在匿名函数中,因此不会被连续循环覆盖。代码中的setInterval函数仅将引用保留为i的最后一个值。

答案 2 :(得分:4)

您不必使用setInterval语句的for循环。试试这个:

var list = Array(...);
var x = 0;

setInterval(function() {

    if (x < list.length;) {
        list[x] += 10;
        console.log(x+"=>"+list[x]);
    }

    else return;

    x++;
}, 5000);

答案 3 :(得分:2)

我不知道如何使用for循环执行此操作,但此处的代码将按时间间隔打印出数组中的每个元素:

function displayText(str) {
   $('.demo').append($('<div>').text(str));
}
var i = 0;

var a = [12, 3, 45, 6, 7, 10];

function timedLoop() {
setTimeout(function () {
    displayText(a[i]);
    i++;
    if(i < a.length) {
        timedLoop();
    }
}, 2000)
}

timedLoop();

使用一些jquery在浏览器中显示它。

答案 4 :(得分:0)

如果你有JSON数组和jQuery,你可以使用:

$.each(jsonArray, function(i, obj) {
    setInterval( function() {
        console.log(i+' '+obj);
    }, 10);
});

答案 5 :(得分:0)

您可以结合使用forEachsetTimeout来按间隔遍历数组。

let modes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let interval = 1000; //one second
modes.forEach((mode, index) => {

  setTimeout(() => {
    console.log(mode)
  }, index * interval)
})