使用FileReader在Javascript中同步读取多个文件

问题描述 投票:0回答:2

我有一个for循环迭代文件的数量

我必须读取每个文件的第一行并将其添加到一个以文件名作为键的Map和该文件的第一行作为值。

我使用FileReader来读取文件,但它是异步的。

当我打开一个流来读取文件时,循环会增加,然后我才能读完文件并将所需的条目添加到地图中。

我需要一个同步操作,即读取第一行,将其添加到Map,然后递增循环并继续下一个文件。

for (var i = 0; i < files.length; i++){

    var file = files[i];

    var reader = new FileReader();

    reader.onload = function(progressEvent){
    var lines = progressEvent.target.result.split('\n');
    firstLine = lines[0];
    alert('FirstLine'+firstLine);   
    //add to Map here 
    }

    reader.readAsText(file);
}

如何修改代码以实现上述功能。

javascript asynchronous synchronization filereader
2个回答
3
投票

您可以使用promises,让它们按照您使用reduce创建它们的顺序运行。

下面的代码显示了如何以这种方式完成,你可以看看这个简单的JSFiddle演示了这个想法。

//create a function that returns a promise
function readFileAndAddToMap(file){
    return new Promise(function(resolve, reject){
        var reader = new FileReader();
        reader.onload = function(progressEvent){
            var lines = progressEvent.target.result.split('\n');
            firstLine = lines[0];
            console.log('FirstLine'+firstLine);   
            //add to Map here 
            resolve();
        }

        reader.onerror = function(error){
            reject(error);
        }

        reader.readAsText(file);
    });
}

//create an array to hold your promises
var promises = [];
for (var i = 0; i < files.length; i++){
    //push to the array
    promises.push(readFileAndAddToMap(files[i]));
}

//use reduce to create a chain in the order of the promise array
promises.reduce(function(cur, next) {
    return cur.then(next);
}, Promise.resolve()).then(function() {
    //all files read and executed!
}).catch(function(error){
    //handle potential error
});

0
投票

我面临同样的问题,我做的是我删除了for循环并使用recursive function代替。这样,我就能够处理FileReader的序列。

下面我尝试根据我的逻辑修改你的代码。如果您需要更清晰,请随时在评论中提出任何问题。

attachmentI = { i: files.length };

function UploadMe() {
   attachmentI.i--;
   if(attachmentI.i > -1){
      var file = files[attachmentI.i];
      var reader = new FileReader();
      reader.onload = function(progressEvent){
         var lines = progressEvent.target.result.split('\n');
         firstLine = lines[0];
         alert('FirstLine'+firstLine);   
         //add to Map here
         UploadMe();
      }
   reader.readAsText(file);
   }
© www.soinside.com 2019 - 2024. All rights reserved.