Pass a parameter to FileReader onload event

守給你的承諾、 提交于 2019-11-27 13:53:51

问题


I need to read some csv files, given by the user. Files are passed to the page/script using a drag and drop div, that handles the file drop as follows:

function handleFileDrop(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files; // FileList object.
    ...
}

I need to parse each file with a csv library that converts it into an array, but I also need to keep track of the file name I'm currently parsing. Here's the code I use to parse each file:

for(var x = 0; x < files.length; x++){
    var currFile = files[x];
    var fileName = currFile.name;
    var reader = new FileReader();
    reader.onload = (function(theFile){
        return function(e){
            var csvArr = CSV.csvToArray( e.target.result, ";", true );
            console.log(csvArr); 
        };
    })(currFile);   
    reader.readAsText(currFile);
}

Until this, everything works great. What I need is to also pass the filename to the reader.onload event, eg:

reader.onload = (function(theFile){
    return function(e){

       ***** I need to have fileName value HERE *****

    };
})(currFile); 

Is possible? How can I do this? Thanks in advance for any help, best regards


回答1:


Try the following:

var reader = new FileReader();
reader.onload = (function(theFile){
    var fileName = theFile.name;
    return function(e){
        console.log(fileName);
        console.log(e.target.result);
    };
})(currFile);   
reader.readAsText(currFile);

Here, you're creating a new fileName variable each time a file is passed to the outer method. You're then creating a function which has access that variable (due to the closure) and returning it.




回答2:


Use Blob API

Using the new File / Blob API it can be done much easier.

Your second code block - also solving your problem - could be rewritten as:

for (let file of files){
 (new Blob([file])).text().then(x=>console.log(file.name,x));
}

The Blob API uses Promises instead of Events like the Filereader API, so much less troubles with closures. Also the Arrow function (x=>) and iterator for of, make the code much more concise.

Check support.

Use Fetch API

Also using the Fetch API Response Object it can be done more easy.

for (let file of files){
 (new Response(file)).text().then(x=>console.log(file.name,x));
}

Note of the missing Array [] in the constructor.

Also check support.



来源:https://stackoverflow.com/questions/16937223/pass-a-parameter-to-filereader-onload-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!