等到异步读取所有文件(FileReader),然后运行代码

soo*_*gui 6 javascript asynchronous filereader

我有一个页面,用户可以在其中选择一个文件夹来上传文件。在发送文件之前,我需要阅读它们并检查数据。我的代码组织如下:

$( '#folder-select' ).on('change', getValidFileList);
var fileList = [];

var getValidFileList = function(event) {

    //Get the selected files
    files  = $( this ).get(0).files;

    for(var i=0; i<files.length; i++) {
        checkFile(files[i]);
    }
    //Do something with the final fileList
    console.log(fileList);
};

var checkFile = function(file) {
    var reader = new FileReader();
    reader.onload = function (event) {
        //Here I parse and check the data and if valid append it to fileList
    };
    reader.readAsArrayBuffer(file);

};
Run Code Online (Sandbox Code Playgroud)

我想使用生成的 fileList 数组来继续处理/显示上传的文件。我发现 reader.onload() 是异步调用的,所以console.log(fileList)afterfor循环的结果是一个空数组(它在reader.onload()触发之前执行)。有没有办法等到所有文件都被读取并附加到fileList?

小智 7

只需跟踪与已提供的文件数量相比已处理的文件数量:

function getValidFileList(files, callback) {

  var count = files.length;              // total number of files
  var fileList = [];                     // accepted files

  //Get the selected files
  for(var i = 0; i < count; i++) {       // invoke readers
    checkFile(files[i]);
  }

  function checkFile(file) {
    var reader = new FileReader();
    reader.onload = function(event) {
      var arrayBuffer = this.result;
      //Here I parse and check the data and if valid append it to fileList
      fileList.push(arrayBuffer);        // or the original `file` blob..
      if (!--count) callback(fileList);  // when done, invoke callback
    };
    reader.readAsArrayBuffer(file);
  }
};
Run Code Online (Sandbox Code Playgroud)

--count会减去每个读者的onload灾区之一。当 =0(或 !count)时,它会调用回调。请注意,数组顺序可能与 files[n] 中的顺序不同,这应该很重要。

然后像这样调用它:

$( '#folder-select' ).on('change', function() {
  getValidFileList(this.files, onDone)
});

function onDone(fileList) {
  // continue from here
}
Run Code Online (Sandbox Code Playgroud)