考虑以下示例:
var cb = function (t) {
console.log('callback -->' + t);
};
for(var i = 0; i<3; i++) {
console.log(i);
setTimeout(function(){
cb(i);
},1000);
}
此代码段的输出为:
0
1
2
callback ---> 3
callback ---> 3
callback ---> 3
一切都按预期工作,for循环将3个回调调用放入事件循环中。在for循环结束时i == 3并且当回调被执行时,所有这些都打印3,因为它们包含到i的链接,即3。 如何改进这个片段,以便在回调执行时它使用传递给它的实际值。
输出应为:
callback ---> 1
callback ---> 2
callback ---> 3
提前致谢。
答案 0 :(得分:18)
Create a closure以便setTimeout
处理程序将引用闭包的局部变量(在本例中,我们也命名为i
),而不是来自循环的i
:
for (var i = 0; i < 3; i++) {
(function (i) {
console.log(i);
setTimeout(function () {
cb(i);
}, 1000);
}(i));
}
答案 1 :(得分:5)
您可以尝试 .bind :
for(var i = 0; i<3; i++) {
console.log(i);
setTimeout(cb.bind(null, i),1000);
}
的 The demo. 强> 的
处理此问题的传统方法是创建一个闭包:
for(var i = 0; i<3; i++) {
console.log(i);
setTimeout((function(i){return function(){cb(i)}}(i)),1000);
}
答案 2 :(得分:3)
一个经常出现的问题。 让我们尝试使用JS未来的一些功能。我的意思是让。 它创建局部范围变量,您不需要使用闭包或其他技巧。 但现在它仅适用于FF(我正在使用20.0.1)
for(var i = 0; i<3; i++) {
console.log(i);
let a = i;
setTimeout(function(){
cb(a);
},1000);
}
答案 3 :(得分:1)
我将在您的cb的functoin
中使用setTimeout()
var cb = function (t) {
setTimeout(function(){
console.log('callback -->' + t);
},1000);
};
for(var i = 0; i<3; i++) {
console.log(i);
cb(i);
}