FileReader onloadend中循环变量的值

时间:2015-03-17 15:19:32

标签: javascript filereader

我正在尝试处理通过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 ++之后该值不会丢失),但是没有工作

2 个答案:

答案 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变量。