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