代码有一个问题,即在调用异步函数时,变量会被覆盖。怎么修好?
代码:
for (x in files) {
asynchronousFunction(var1, var2, function(){
console.log(x.someVaraible);
});
}
现在的问题是,当调用asynchronousFunction中的回调函数时,x.files变量已更新为json数组文件中的下一个变量。我希望变量应包含先前的值。
回调函数中的变量数量不能更改,因此无法在回调函数中发送变量名称。
答案 0 :(得分:12)
在javascript中使用'local'变量的问题是你的变量实际上有函数作用域,而不是块作用域 - 比如java和c#etc有
解决此问题的一种方法是使用具有块范围的let
,但目前只有firefox支持此功能。
所以这段代码只适用于firefox:
for (var x in files) {
// This variable has BLOCK scope
let file = files[x];
asynchronousFunction(var1, var2, function(){
console.log(file.someVaraible);
});
}
对于其他浏览器,替代方法是使用闭包
for (var x in files) {
var file = files[x];
asynchronousFunction(var1, var2, (function(file){
return function() {
console.log(file.someVaraible);
};
})(file);
}
另一种方法是使用map / forEach,假设文件的数据类型是数组。
files.forEach(function(file) {
asynchronousFunction(var1, var2, function(){
console.log(file.someVaraible);
});
});
如果它不是数组,那么你总是可以使用这种技术
[].forEach.call(files, function(file) {
asynchronousFunction(var1, var2, function(){
console.log(file.someVaraible);
});
});
更全面的写作方式当然是
Array.prototype.forEach.call(files, function(file) {
// As before
但我觉得[].forEach
眼睛更好
答案 1 :(得分:1)
您需要将x
从回调函数创建的闭包中解开。简短的回答:
for (x in files) {
asynchronousFunction(var1, var2,
(function(y){
return function(){
console.log(y.someVaraible);
}
})(x)
);
}
如需更长的答案和解释,请参阅我对上一个问题的回答:Please explain the use of JavaScript closures in loops
答案 2 :(得分:0)
您需要将变量绑定到函数定义,或将变量传递给函数。我可能采取一种组合方法,例如:
for (x in files) {
var local_x = x;
var fn = function () {
theRealFunction( local_x );
};
asynchronousFunction(var1, var2, fn);
}
虽然在你的例子中我不需要调用theRealFunction()作为它的少量代码(只是console.log)。
答案 3 :(得分:0)
X迭代,所以在调用回调函数时,x将是循环中最后一个迭代函数。
通过像这样设置x
本地修复:
for (x in files) {
(function() {
var x = arguments[0];
asynchronousFunction(var1, var2, function() {
console.log(x.someVaraible);
});
}(x));
}