FileReader onloadend 中循环变量的值
value of loop variable in FileReader onloadend
我正在尝试处理通过 html5 dropzone/fileinput 创建的文件列表。 files[] 实际上不是一个 FileList,而是一个包含 File 对象的数组。
只要 files[] 仅包含 1-2 个文件,此方法就有效,但突然有更多文件时,每个控制台输出都是相同的(files[] 中的最后一个文件)。例如,对于 4 个文件,我得到 4 次 "filereader.onloaded: File: save-view.html index:4",其中 save-view.html 是最后一个文件。
for(var i=0; i < files.length; i++)
{
var filereader = new FileReader();
filereader.myfile = files[i];
filereader.myindex = i;
filereader.onloadend = function()
{
console.log("filereader.onloaded: File: "+filereader.myfile.name+" index:" +filereader.myindex);
//here we call some other functions which most likely don't cause any problems
}
filereader.readAsArrayBuffer(file);
}
我已经尝试了很多,比如创建一个 filereader 数组(这样 var filereader 永远不会被覆盖),并将索引保存为 filereader 的附加成员变量(这样值在 i++ 之后不会丢失),但是 none 有效。
filereader
随着循环的每次迭代而变化,并且循环不会在每次继续之前等待回调触发。因此,每当触发 onload 回调时,filereader
可能没有与特定 onload 事件关联的 FileReader 对象。
要确保您在回调中使用正确的 FileReader 对象,请使用 this
关键字,或者您可以从传递给回调的事件对象中获取它;
filereader.onloadend = function(event)
{
console.log("filereader.onloaded: File: "+this.myfile.name+" index:" +event.target.myindex);
//here we call some other functions which most likely don't cause any problems
}
你需要适当的关闭。在 Javascript 中,变量的范围不取决于花括号,而是取决于它们所在的函数。所以即使你的变量是在 for 循环中定义的,它实际上也可以在它之外使用,并且它是整个循环中唯一一个相同的变量。
您可以通过添加适当的闭包来解决此问题:
for(var i=0; i < files.length; i++)
{
(function(f, i)
{
var filereader = new FileReader();
filereader.onloadend = function()
{
console.log("filereader.onloaded: File: "+f.name+" index:" +i);
//here we call some other functions which most likely don't cause any problems
}
filereader.readAsArrayBuffer(file);
})(files[i], i);
}
请注意,for 循环中定义的 i
现在是与匿名函数参数列表中定义的 i
不同的变量。通过将变量传递给函数,它们将被复制到新变量中,这些变量将在整个脚本中保持独立。此外,现在会为 for 循环的每次迭代创建一个新的 filereader
变量。
我正在尝试处理通过 html5 dropzone/fileinput 创建的文件列表。 files[] 实际上不是一个 FileList,而是一个包含 File 对象的数组。
只要 files[] 仅包含 1-2 个文件,此方法就有效,但突然有更多文件时,每个控制台输出都是相同的(files[] 中的最后一个文件)。例如,对于 4 个文件,我得到 4 次 "filereader.onloaded: File: save-view.html index:4",其中 save-view.html 是最后一个文件。
for(var i=0; i < files.length; i++)
{
var filereader = new FileReader();
filereader.myfile = files[i];
filereader.myindex = i;
filereader.onloadend = function()
{
console.log("filereader.onloaded: File: "+filereader.myfile.name+" index:" +filereader.myindex);
//here we call some other functions which most likely don't cause any problems
}
filereader.readAsArrayBuffer(file);
}
我已经尝试了很多,比如创建一个 filereader 数组(这样 var filereader 永远不会被覆盖),并将索引保存为 filereader 的附加成员变量(这样值在 i++ 之后不会丢失),但是 none 有效。
filereader
随着循环的每次迭代而变化,并且循环不会在每次继续之前等待回调触发。因此,每当触发 onload 回调时,filereader
可能没有与特定 onload 事件关联的 FileReader 对象。
要确保您在回调中使用正确的 FileReader 对象,请使用 this
关键字,或者您可以从传递给回调的事件对象中获取它;
filereader.onloadend = function(event)
{
console.log("filereader.onloaded: File: "+this.myfile.name+" index:" +event.target.myindex);
//here we call some other functions which most likely don't cause any problems
}
你需要适当的关闭。在 Javascript 中,变量的范围不取决于花括号,而是取决于它们所在的函数。所以即使你的变量是在 for 循环中定义的,它实际上也可以在它之外使用,并且它是整个循环中唯一一个相同的变量。
您可以通过添加适当的闭包来解决此问题:
for(var i=0; i < files.length; i++)
{
(function(f, i)
{
var filereader = new FileReader();
filereader.onloadend = function()
{
console.log("filereader.onloaded: File: "+f.name+" index:" +i);
//here we call some other functions which most likely don't cause any problems
}
filereader.readAsArrayBuffer(file);
})(files[i], i);
}
请注意,for 循环中定义的 i
现在是与匿名函数参数列表中定义的 i
不同的变量。通过将变量传递给函数,它们将被复制到新变量中,这些变量将在整个脚本中保持独立。此外,现在会为 for 循环的每次迭代创建一个新的 filereader
变量。