import * as fs from 'fs';
const filesDir: string = './src/200k';
function uniqueValues() {
let arr : string[] = [];
fs.readdir(filesDir, function(err, files){
files.forEach(function(file){
fs.readFile(filesDir '/' file, 'utf8', function(err, data){
arr.push(...data.toString().split("\n"));
})
})
});
return new Set(arr).size;
}
console.log(uniqueValues())
why does the uniqueValues() return an empty array? can someone explain pls?
CodePudding user response:
fs.readdir
and fs.readFile
are asynchronous functions. The result of their operations is only available in their callback functions.
Here is what you are currently doing:
- declare new empty array
arr
- read the content of a directory and when it's done, do other stuff
- return a new Set based on the previously declared array which does not yet contain any value yet (hence the empty array returned). (Actually with your current code, you are returning the size of the Set but I think it's a typo).
So basically in your case, you return an empty array while NodeJS is reading a directory and the contents of other files, which all get lost...
If you want to return an array with the results, using asynchronous functions, you need to work with promises and return the promise of an array.
Here is what it should look like:
import {readdir, readFile} from 'fs/promises';
const filesDir = './src/200k';
async function uniqueValues() {
const files = await readdir(filesDir);
const filesContent = await Promise.all(files.map((file) => {
return readFile(filesDir '/' file, 'utf8');
}));
const arr = filesContent.reduce((acc, data) => {
acc.push(data.toString().split('\n'))
return acc;
}, [])
return new Set(arr);
}
uniqueValues().then((values) => {
console.log(values);
})