看到很多帖子谈论setTimeout
和关闭,但我仍然无法传递一个简单的 for 循环计数器。
for (i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, Math.floor(Math.random() * 1000));
}
给
5
5
5
5
5
想拥有
0
1
2
3
4
怎么了 ?
请不要发火,我以为我已经理解了这个setTimeout()
故事,但显然没有。
看到很多帖子谈论setTimeout
和关闭,但我仍然无法传递一个简单的 for 循环计数器。
for (i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, Math.floor(Math.random() * 1000));
}
给
5
5
5
5
5
想拥有
0
1
2
3
4
怎么了 ?
请不要发火,我以为我已经理解了这个setTimeout()
故事,但显然没有。
您可以使用闭包来保持i
对循环内当前值的引用:
for (i = 0; i < 5; i++) {
(function(i) {
setTimeout(function () {
console.log(i);
}, Math.floor(Math.random() * 1000));
})(i); //Pass current value into self-executing anonymous function
}
但是,这不太可能按顺序打印数字,因为您使用了随机超时(您可以i * 1000
改为使用以升序打印数字,相隔一秒)。
这是一个工作示例。
您需要传递i
给setTimeout
. 当你的第一个方法被执行时,i
已经设置为 5。
由于您的超时因调用而可变Math.Random()
,因此超时将有所不同,并且您不会按照您期望的顺序获得它们。
for (i = 0; i < 5; i++) {
(function(i) {
setTimeout(function () {
console.log(i);
}, 1000);
})(i);
}
更改Math.floor(Math.random() * 1000)
为简单地1000
确保函数按照您期望的顺序执行。
您需要将“有趣”的代码包装在一个函数中,该函数关闭i
并将其复制到局部变量中:
for (i = 0; i < 5; i++) {
(function() {
var j = i;
setTimeout(function () {
console.log(j);
}, Math.floor(Math.random() * 1000));
})();
}
“中间”函数调用强制将值j
固定在调用函数的点,因此在每个setTimeout
回调中,值j
是不同的。