我有这个示例代码:
for (var i = 0; i < array.length; i++) {
$.getJSON("http://someapi", { "one": two }, function (result) {
array[i].value = result.value;
});
}
然而,回调函数中的i变量与人们所期望的不一致。 for循环运行得非常快,并且在第一个回调函数接收到答案之前完成,因此i变量在循环中的某个位置甚至完成并越过数组边界。
无论如何,有没有办法将变量传递给回调函数?像这样:
$.getJSON("http://someapi", { "one": two }, function (result, i) {
array[i].value = result.value;
});
答案 0 :(得分:4)
for (var i = 0; i < array.length; i++) {
$.getJSON("http://someapi", { "one": two }, (function(j) {
return function (result) {
array[j].value = result.value;
};
})(i)); // Immediate invocation is your best friend
}
您可以在宣布回调时传递i
变量(而不是像在代码中那样进行评估)。
答案 1 :(得分:3)
创建一个额外的闭包来存储当前索引并在实际函数中使用它应该可以做到这一点,类似于:
for (var i = 0; i < array.length; i++) {
$.getJSON("http://someapi", {
"one": two
}, (function () { // added closure...
var currentIndex = i; //...to allow declaration of additinal variables
return function (result) {
array[currentIndex].value = result.value; // use currentIndex here
};
})()); // () force immidiate execution
}
DEMO - 比较不使用闭包和使用闭包的结果
打开DEMO,然后单击运行,观察控制台输出。
DEMO的代码:
var array = [1, 2, 3, 4, 5];
// Wihtout closure i is not always as expected.
for (var i = 0; i < array.length; i++) {
$.getJSON("#", {
"one": 1
}, function (result) {
console.log('no-closure: ' + i);
});
}
// With closure stored i (currenIndex) is in the expected order
for (var i = 0; i < array.length; i++) {
$.getJSON("#", {
"one": 1
}, (function () {
var currentIndex = i;
return function (result) {
console.log('closure: ' + currentIndex);
};
})());
}