简体   繁体   English

对于Javascript中的循环仅从最后一次迭代输出值

[英]For Loop in Javascript outputs value only from last iteration

I have this Javascript code, which works as expected: 我有这个Javascript代码,按预期工作:

<div class="test"></div>

<script>
setTimeout(function(){$(".test").append("test1")},1000);
setTimeout(function(){$(".test").append("test2")},2000);
</script>
<script src="js/jquery.min.js"></script>

It shows "test1" first and then "test2" a second later, as such: "test1test2", which is what I want. 它首先显示“test1”,然后在一秒后显示“test2”,因此:“test1test2”,这就是我想要的。

When I try to do this in a FOR loop, like this: 当我尝试在FOR循环中执行此操作时,如下所示:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++ ) {
    setTimeout(function(){$(".test").append("test" + i)},timeInterval);
    timeInterval += 1000;
}

Then I get "test2" first and then "test2" a second later, as such: "test2test2", which is not what I want. 然后我先得到“test2”,然后在第二次得到“test2”,这样:“test2test2”,这不是我想要的。

In fact, if l = 3, then I get "test3test3test3" instead of "test1test2test3". 事实上,如果l = 3,那么我得到“test3test3test3”而不是“test1test2test3”。 Does anybody know how to solve this problem? 有人知道如何解决这个问题吗?

The var i is incremented to 2 when the setTimeout is executing the function and so it just prints the i value as 2 resulting in test2test2 . setTimeout执行函数时,var i增加到2,因此它只将i值打印为2,从而得到test2test2

You should use a closure to use the instance of i which will print test1test . 你应该使用一个闭包来使用i的实例来打印test1test

DEMO: http://jsfiddle.net/mBBJn/1/ 演示: http //jsfiddle.net/mBBJn/1/

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++) {
    (function(i) {
        setTimeout(function() {
            $(".test").append("test" + (i+1))
        }, timeInterval);
        timeInterval += 1000;
    })(i);
}

Edit: used function args. 编辑:使用函数args。

The for loop doesn't create a new scope, you can use another function to do it: for循环不会创建新范围,您可以使用其他函数来执行此操作:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++) {
    setTimeout((function(i) {
        return function() {
            $(".test").append("test" + i);
        }
    })(i), timeInterval);
    timeInterval += 1000;
}

The variable i will always refer to the current value of i (not the value of i when called) in this situation. 变量i总是引用的当前值i (没有价值i在这种情况下调用时)。

That's how scope works in JavaScript. 这就是范围在JavaScript中的工作原理。

See the answer by @Esailija for a solution. 请参阅@Esailija的答案以获得解决方案。

This is because you aren't capturing the value of i from the for-loop. 这是因为您没有从for循环中捕获i的值。 You can tweak your code to this to make it work: 您可以调整代码以使其工作:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++ ) {
    (function(i2, timeInterval2) {
        setTimeout(function() {
            $(".test").append("test" + i2);
        }, timeInterval2);
    })(i, timeInterval);
    timeInterval += 1000;
}

The most obvious way to keep i in scope is solved in other answers, but since you're using jQuery you have other options. 保持i在范围内最明显的方法是在其他答案中解决,但由于你使用jQuery,你还有其他选择。

  1. Use $.each instead of for loop, that way you have access to i variable anywhere in that scope. 使用$.each而不是for循环,这样你就可以在该范围内的任何地方访问i变量。

  2. Use delay instead of setTimeout . 使用delay而不是setTimeout For this to work you need to trigger a queue first: $(".test").show(0).delay(timeInterval).append("test" + i) 为此,您需要首先触发队列: $(".test").show(0).delay(timeInterval).append("test" + i)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM