Reputation: 821
for(var x = 19; x <= 29; x = x + 1) {
if(x < 29) {
if(values[x]) {
var reader = new FileReader();
var file = $(`#${keys[x]}`)[0].files[0];
reader.readAsDataURL(file);
reader.onloadend = function () {
values[x] = reader.result.slice(reader.result.indexOf(',')+1);
};
}
} else {
insertAll();
}
}
the code above only returns the last file and skips all others because it takes time to finish so how do i make sure loop won't continue without finishing reading file
Upvotes: 0
Views: 53
Reputation: 22911
Recursion can get a little ugly. You should wrap them in promises, and use new es6 await/async
syntax:
function readValues(filename) {
return new Promise((resolve) => {
const reader = new FileReader();
const file = $(`#${filename}`)[0].files[0];
reader.readAsDataURL(file);
reader.onloadend = function() {
resolve(reader.result.slice(reader.result.indexOf(',')+1));
};
});
}
async function main() {
let results = {};
for(let x = 19; x < 29; x++) {
if(values[x]) {
results[x] = await readValues(keys[x]);
}
}
insertAll(results);
}
main();
For reading all the files at the same time, I recommend using Promise.all
:
function readValues(filename) {
return new Promise((resolve) => {
const reader = new FileReader();
const file = $(`#${filename}`)[0].files[0];
reader.readAsDataURL(file);
reader.onloadend = function() {
resolve(reader.result.slice(reader.result.indexOf(',')+1));
};
});
}
async function main() {
let promises = [];
let results = {};
for(let x = 19; x < 29; x++) {
if(values[x]) {
const task = readValues(keys[x])
// Assign the values in results
.then(res => results[x] = res);
promises.push(task);
}
}
await Promise.all(promises);
// Results is now an object that you can use.
insertAll(results);
}
main();
Upvotes: 2
Reputation: 22474
You can use recursion instead of a loop, here is an example:
function recursion(x){
if(x < 29) {
if(values[x]) {
var reader = new FileReader();
var file = $(`#${keys[x]}`)[0].files[0];
reader.readAsDataURL(file);
reader.onloadend = function () {
values[x] = reader.result.slice(reader.result.indexOf(',')+1);
recursion(++x)
};
}
} else {
insertAll();
}
}
recursion(19)
// You get here only after all the files are read.
The idea is to start reading the next file only after you finish reading the current one (recursion(...)
is called inside the reader.onloadend
callback)
Upvotes: 3
Reputation: 403
create other function to handle read file
for(var x = 19; x <= 29; x = x + 1) {
if(x < 29) {
if(values[x]) {
readData(x);
}
} else {
insertAll();
}
}
function readData(x){
var reader = new FileReader();
var file = $(`#${keys[x]}`)[0].files[0];
reader.readAsDataURL(file);
reader.onloadend = function () {
values[x] = reader.result.slice(reader.result.indexOf(',')+1);
};
}
Upvotes: -1