Reputation: 69
I pass a callback to fs.writeStream, and for some reason any tasks after it are being called first, before the callback is executed.
async function writeFile(file, callBack) {
// awaiting this also doesn't work
fs.writeFile(arg1, arg2, arg3, (error) => callBack(error))
}
async function task() {
let count = 0;
const callBack = (error) => {
if (error) {
count--;
} else {
count++;
}
}
for(const file of files) { // files.length = 1
await writeFile(file, callBack);
}
console.log(count) // Prints 0, should be 1. Why does this get called before the callback?
}
Upvotes: 0
Views: 5341
Reputation: 17407
First of all, you are calling it wrong. If you want to wait for an async function you have to call it like this with await
await yourFunction(...);
and not like this with async
async yourFunction();
Second, you are obviously mixing async
functions and functions with callbacks. Ie, when you have
async function yourFunction() {
anotherFunction((error, data) => {
...
});
}
you are actually returning a Promise<void>
which immediately resolves. async
function do not wait for any callbacks of callback-based functions.
And third, you are not using the file
parameter of your writeFile(file, callBack)
function, but three completely undefined arguments arg1, arg2, arg3
For your current problem, there are two possibilities
You import the promise functions of the fs
module and use them properly (available since Node v10)
const fsp = require("fs").promises;
async function writeFile(filename, data, errorHandler) {
try{
await fsp.writeFile(filename, data);
} catch (e) {
errorHandler(e);
}
}
You import the classic callback-form of the fs module and wrap the functions into a promise
const fs = require("fs");
async function writeFile(filename, data, errorHandler) {
return new Promise((resolve, reject) => {
fs.writeFile(filename, data, (e) => {
if (e) {
errorHandler(e);
// if you want to continue and adjust the count
// even if the writeFile failed
// you don't need the reject here
return reject(e);
}
resolve();
});
});
}
Upvotes: 2
Reputation: 3743
Given you imported the correct fs library, namely fs/promises
, your answer should look like this:
async function writeFile(file) {
await fs.writeFile(file);
}
async function task() {
let count = 0;
const callBack = (error) => {
if (error) {
count--;
} else {
count++;
}
}
for(const file of files) { // files.length = 1
await writeFile(file);
}
console.log(count) // Prints 0, should be 1. Why does this get called before the callback?
}
You were missing the required await
to actually await the asynchronous result of fsPromises.writeFile
as you can see here: https://nodejs.org/dist/latest-v15.x/docs/api/fs.html#fs_fspromises_writefile_file_data_options
Also if you're using the promise based fs you will not have nor need the callback (ftfy)
If you still want to count, do it like this:
async function writeFile(file) {
await fs.writeFile(file);
}
async function task() {
let count = 0;
for (const file of files) { // files.length = 1
try {
await writeFile(file);
count++; // <-------- NOTICE THIS PART HERE
} catch (e) {
count--;
}
}
console.log(count) // Prints 0, should be 1. Why does this get called before the callback?
}
Upvotes: 0