I have a function will send all the images that located inside the "samples" folder to extractImage function, then, the extractImage function will call 3rd party API to perform its operation. But when I try to console.log(arr), it seem like didn't even be called. I think I have did something wrong to handling the async, could someone help me to have a look. I have quick new to JavaScript.
let arr = [];
await fs.readdir("samples", async (err, files) => {
console.log(files);
files.map(async (val) => {
console.log(val);
let tt = await extractImage(val);
return arr.push(tt);
});
});
fs.writeFileSync("final.json", "s");
console.log(arr);
console.log("tt");
4 Answers 4
You didn't use fs.readdir() correctly, and it should be const files = await readdir(path). And your files.map(async (val) => {...}) will return a list of promises immediately, and console.log(arr) might be executed even before these promises resolve. The code might be like the following one:
let files = await fs.readdir("samples")
console.log(files);
let promises = files.map(async (val) => {
let tt = await extractImage(val);
return tt;
});
let arr = await Promise.all(promises)
console.log(arr);
console.log("tt");
fs.writeFileSync("final.json", "s");
Comments
I might consider using promisify in this instance, and then returning an array of promises from the files, and getting your data when all of those have been resolved.
const util = require('util');
const fs = require('fs');
const readdirP = util.promisify(fs.readdir);
async function main() {
try {
const files = await readdirP('samples');
const promises = files.map(file => extractImage(file));
const data = await Promise.all(promises);
} catch(error) {
console.log(error);
}
}
main();
Comments
EDIT:
awaitcannot be used in a global context.fs.readdirdoes not return a promise. It is callback based, which means you cannot await it. However, there is a synchronous version of the method:fs.readdirSync.- As of Node 11, you can do this:
const fs = require('fs').promises
which allows the use of await and .then on fs. For lower versions, you can use util.promisify.
1 Comment
Using a self-invoked function could help in this case:
(async function () {
let arr = [];
await fs.readdir("samples", async (err, files) => {
console.log(files);
files.map(async (val) => {
console.log(val);
let tt = await extractImage(val);
return arr.push(tt);
});
});
fs.writeFileSync("final.json", "s");
console.log(arr);
console.log("tt");
});
const files = await readdir(path);