为什么我的迭代器变量会继续重置?

时间:2016-05-25 03:14:35

标签: javascript jquery

我有一个填充了数字的数组。我想在alert()弹出窗口中每隔5秒显示一个新号码。我看起来大部分工作,但它在显示数字3之前重置。首先它显示1,然后它显示2,然后它再次显示1。我无法弄清楚。如果可以的话,我想在大多数情况下保持这种语法。我只是不明白为什么counter一直重置为0。

var arr = [1, 2, 3, 4, 5];
var maxLoops = Number(arr.length);
var counter = -1;

(function next() {
    if (counter++ > maxLoops);
    setTimeout(function() {
        alert(arr[counter]);
        next();
    }, 5000);
})();

3 个答案:

答案 0 :(得分:1)

这里的问题是counter的值可能会在设置计时器和调用其中的匿名函数之间发生变化。要缓解此问题,必须将counter的值传递给计时器函数。

var arr = [1, 2, 3, 4, 5];
var maxLoops = Number(arr.length) - 1;
var counter = -1;

(function next() {
    if (counter++ >= maxLoops) return;
    setTimeout((function (c) {
        return (function() {
            alert(arr[c]);
            next();
        });
    })(counter), 5000);
})();

就个人而言,我想写如下:

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

(function next(counter) {
    if (counter < arr.length) {
        setTimeout(function () {
            alert(arr[counter]);
            next(counter + 1);
        }, 5000);
    }
})(0);

此实现确保next具有counter的本地副本,其值在函数运行时不会更改,以便超时函数每次都使用正确的counter值。 / p>

如果页面刷新(无论出于何种原因),您还可以将所有超时功能与以下“单行”一起设置:

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

arr.forEach(function (e, i) {
    setTimeout(function () { alert(e); }, 5000 * (i + 1));
});

答案 1 :(得分:0)

不要经常重置计数器,只需继续增加计数器并使用%运算符。例如:

var arr = [1,2,3,4,5],
    counter = 0

setInterval(function() {
    alert(arr[counter++%arr.length])
}, 5000)

代码的内容如下:

alert(
  counter++ // Will increase variable after statement
  % // Modulus Operator: Basically Remainder
  arr.length // The length of the array
)

Read about remainder on MDN

答案 2 :(得分:0)

我建议你这样做:

var arr = [1, 2, 3, 4, 5];
var maxLoops = Number(arr.length);
var counter = 0;

(function next() {
    if (counter >= maxLoops) return;
    setTimeout(function() {
        alert(arr[counter++]);
        next();
    }, 5000);
})();

您需要放置return语句以指示函数必须完成,否则,它将继续使用setTimeout和计数器递增的值。