我正在尝试处理通过html5 dropzone / fileinput创建的文件列表。 files []实际上不是FileList,而是包含File对象的数组。
只要files []只包含1-2个文件,这就有效,但是每个控制台输出的文件突然增多(文件[]中的最后一个文件)。例如,有4个文件,我得到4次" filereader.onloaded:文件:save-view.html索引: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);
}
我尝试了很多像创建文件读取器数组(以便永远不会覆盖var文件读取器)并将索引保存为filereader的附加成员变量(以便在i ++之后该值不会丢失),但是没有工作
答案 0 :(得分:1)
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
}
答案 1 :(得分:1)
你需要适当的关闭。在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
变量。