Reputation: 63
I've got the following function, which doesn't execute in the order I'd like it to.
The console.log within the callback actually gets fired before the loop within the function itself even executes. So to sum it up I'd like the function "getFiles" to fully finish before the next one "createDatabase" starts to execute.
Thanks for your help. I'm already going nuts about this issue :(
const fs = require("fs")
let data = []
const getFiles = () => {
fs.readdir("./database/test/", (err, files) => {
files.forEach(file => {
require("../database/test/" + file)
data.push(Number(file.split(".")[0]))
console.log(data)
})
})
}
const createDatabase = () => {
data.sort((a, b) => {
return a-b
})
console.log(data)
// Do some other stuff
}
const run = async () => {
await getFiles
await createDatabase()
process.exitCode = 0
}
run()
Upvotes: 0
Views: 408
Reputation: 7770
I am not really sure what exactly you are trying to do but looks like the problem is in your run function. You are not calling getFiles function inside run. You care just mentioning the function name. Also needs to wrap the getFiles
in promise it should be
const run = async () => {
await getFiles();
await createDatabase();
process.exitCode = 0
}
Upvotes: -1
Reputation: 707976
This would be fairly straightforward to code with the newer fs.promises
interface so you can await
the readdir()
output:
const fsp = require('fs').promises;
const path = require('path');
const async getFiles = () => {
const root = "./database/test/";
let files = await fsp.readdir(root);
return files.map(file => {
require(path.join(root, file));
return Number(file.split(".")[0]);
});
}
const createDatabase = (data) => {
data.sort((a, b) => {
return a-b
})
console.log(data)
// Do some other stuff
}
const run = async () => {
let data = await getFiles();
createDatabase(data);
process.exitCode = 0
}
run().then(() => {
console.log("all done");
}).catch(err => {
console.log(err);
});
Summary of Changes:
await
the results of readdir()
.getFiles()
to be async
so we can use await
and so it returns a promise that is resolved when all the asynchronous work is done.data
into the functions (resolved from getFiles()
and passed to createDatabase()
) rather than being a top level variable that is shared by multiple functions.run()
getFiles()
with parens after it in run()
.Upvotes: 2
Reputation: 156
Following code snippet will first completely run getFiles function and then run the createDatabase function. For using async/await, a function needs to return a promise(Read about promises here).
const fs = require("fs")
let data = []
const getFiles = () => {
return new Promise((resolve, reject) => {
fs.readdir("./database/test/", (err, files) => {
if (err) {
reject(err);
}
files.forEach(file => {
require("../database/test/" + file)
data.push(Number(file.split(".")[0]))
console.log(data)
})
resolve(true);
})
})
}
const createDatabase = () => {
data.sort((a, b) => {
return a-b
})
console.log(data)
// Do some other stuff
}
const run = async () => {
await getFiles();
await createDatabase();
process.exitCode = 0;
}
run()
Since the createDatabase function is not returning any promise right now, you can remove await in front of it. Await is used only if a promise is returned. You can read about async/await here.
Upvotes: 1
Reputation: 41
The problem is related to using a forEach loop for asynchronous code. This answer has more on the issue:
Using async/await with a forEach loop
Upvotes: -1