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

时间:2017-03-19 12:55:01

标签: javascript asynchronous filereader

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

this.sendMessage = function(){
    var config = {
        //USE serializer
        transformRequest: $httpParamSerializer,
        headers:{
          'Content-Type':'application/x-www-form-urlencoded',
          'Accept':'application/json, text/javascript, */*;q=0.01'
        }
     };

     var data = {
          '_wpcf7':4,
          '_wpcf7_version':4.7,
          '_wpcf7_locale':'en_US',
          '_wpcf7_unit_tag':'wpcf7-f4-p6-o1',
          'fname':'john',
          'email':'admin@example.com',
          'subject':'subject',
          'message':'message',
          '_wpcf7_is_ajax_call':1
    };


    //vvvv RETURN httpPromise
    return $http.post('/be/home', data, config);
 };

我想获取生成的fileList数组以继续处理/显示上传的文件。我发现reader.onload()是异步调用的,因此$( '#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); }; 循环后console.log(fileList)的结果是一个空数组(它在for被触发之前执行)。有没有办法等到所有文件都被读取并附加到fileList?

1 个答案:

答案 0 :(得分:3)

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

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);
  }
};

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

然后像这样调用它:

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

function onDone(fileList) {
  // continue from here
}