Reputation: 878
I have a for
loop iterating over the number of files
I have to read the first line of each file and add it let's say to a Map having File name as the key and First line of that file as a the value.
I am using FileReader
to read the file but it is asynchronous.
When I open a stream to read the file the loop gets incremented before I am done with reading the file and adding my desired entry to the map.
I need a synchronous operation i.e. Read the First line , add it to the Map and then increment the loop and proceed with the next file.
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);
}
How to modify the code so as to achieve the above mentioned functionality.
Upvotes: 1
Views: 5183
Reputation: 116
I was facing the same issue, what I did was I removed the for
loop and used recursive function
instead. That way, I was able to handle the sequence of FileReader
.
Below I tried to modify your code based on my logic. feel free to ask any question in comments if you need more clarity.
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);
}
Upvotes: 0
Reputation: 8879
You can use promises and let them run in the order you create them using reduce
.
The below code shows how it could be done this way, and you can take a look at this simple JSFiddle that demos the idea.
//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
});
Upvotes: 3