I'm trying to scan a local directory for all of the text files within it, then read each of those files. I want to do it properly using promises, async, and await, but something is going wrong and am stuck trying to figure it out.
I am able to read the directory contents and output all of the filenames correctly, but when I try to read those files themselves using the map
method, I get a Promise { <pending> }
log for each of the files. Also, I get a UnhandledPromiseRejection
error at the end.
I can read a single file fine outside of the map
function, but can't loop through all of the files and read them without getting an error.
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const textFileDir = `${__dirname}/files/`;
const readDirPro = (dir) => {
return new Promise((resolve, reject) => {
fs.readdir(dir, (error, files) => {
if (error) reject('Could not find directory');
resolve(files);
});
});
};
const readFilePro = (file) => {
return new Promise((resolve, reject) => {
fs.readFile(file, 'utf-8', (err, data) => {
if (err) reject('Could not find file');
resolve(data);
});
});
};
const readAllFiles = async () => {
try {
const dirFilesArr = await readDirPro(textFileDir);
// correctly outputs array of file names in directory
// console.log('dirFilesArr: ', dirFilesArr);
// THIS IS THE PROBLEM:
await dirFilesArr.map((file) => {
// console.log(file);
// correctly outputs filenames
const fileContent = readFilePro(file);
// console.log(fileContent);
// incorrectly outputs "Promise { <pending> }" logs for each file
});
} catch (err) {
console.log(`catch (err): ${err}`);
throw err;
}
return '2: final return';
};
(async () => {
try {
console.log('1: readAllFiles!');
const x = await readAllFiles();
console.log(x);
console.log('3: Done!');
} catch (err) {
console.log(`IIFE catch ERROR : ${err}`);
}
})();
Here's is the full console output for that javascript, with the `Promise { } logs commented out:
1: readAllFiles!
2: final return
3: Done!
node:internal/process/promises:289
triggerUncaughtException(err, true /* fromPromise */);
^
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Could not find file".] {
code: 'ERR_UNHANDLED_REJECTION'
}
Node.js v19.0.1
I would prefer to keep the working solution as close to this code as possible, because it's is actually one piece of a larger puzzle, and I need to be able to continue utilizing this structure.
My ultimate goal is to read all of those files, pull certain data from them, then write that data into a new JSON file.
UPDATE: Check this answer below for the most exact solution to the question: https://stackoverflow.com/a/75206022/3787666