Haven't worked with async functions so i'm kind of lost here... What I'm trying to accomplish is to iterate through files in folder that is within a zip file with JSZip, save these files in an array and then sort them, save them to a local variable so I can send them further.
Here is my code where I get an array of promises:
async extractTests(file){
let Zip = new JSZip();
let tests = await Zip.loadAsync(file).then((zip) => {
const promises = [];
zip.folder("tests").forEach(async function (relativePath, file) {
promises.push({ name: relativePath, data: await zip.file("tests/" + relativePath).async("text") });
});
return promises;
})
return tests;
}
Then I'm trying to sort the array in the event function which runs when a zip file is added:
extract(event) {
const file = event.target.files[0];
let res = this.extractTests(file);
res.then(function (r) {
res.sort(function (a, b) {
var nameA = a.name.toUpperCase();
var nameB = b.name.toUpperCase();
console.log(a.name);
if (nameA < nameB) {
return -1;
}
else {
return 1;
}
});
})
}
The list needs to be sorted because it gets resolved in the wrong order - as far as I've gathered is that the sort function doesn't even fire - pretty sure it's something to do with a asynchronous function. The sort would work on local variable and it would be much simpler for me to save the array as a local variable - so how could I do that and resolve the promises.
Thanks in advance
Using async
/ await
on higher-order function is highly discouraged and may lead un-predictable behavior where your code may seem to work but actually only triggers some asynchronous calls without providing the desired output.
I cannot reproduce the issue for sure without having the archive structure with the same library, but you can try to change your extraction function as follows:
async function extractTests(file: any) {
let Zip = new JSZip();
let tests = await Zip.loadAsync(file)
.then((zip) => {
const promises = [];
zip.folder("tests")
.forEach(function (relativePath, file) { // removed async function
promises.push(
zip.file("tests/" + relativePath)
.async("text")
.then((data) => { // replaced with Promise fulfillment data update
return { name: relativePath, data: data }
})
);
});
return promises;
})
return Promise.all(tests); // Resolve all promises in parallel
}