OlaStein OlaStein - 5 months ago 11
Node.js Question

Read files asynchronously

I am trying to read some files and store their name in an array in nodejs. I have made a function. It reads the file, and prints them out in the console, but the output of the array is []. I am assuming it is because node.js is asynchronous, but I thought a callback would fix it?

readCurdir("./uploads/", curDirReadFinn);
function readCurdir(dir, callback){
var tmpArray = [];
fs.readdir(dir, function(err, files){
if(err){
if(err.code==='EISDIR'){}
else{
console.log(err);
}
return;
}
files.forEach(function(file){
fs.readFile(dir + file, 'utf-8', function(err, data){
if(err){
if(err.code==='EISDIR'){}
else{
console.log(err);
}
return;
}
tmpArray.push(file);
console.log(file); //this prints
});
});
});
callback(tmpArray);
}
function curDirReadFinn(array){
console.log(array); //Output: []
}


I have also tried this:

files.forEach(function(file){
fs.readFile(dir + file, 'utf-8', function(err, data){
if(err){
if(err.code==='EISDIR'){}
else{
console.log(err);
}
return;
}
tmpArray.push(file);
counter++;
if(counter === files.lenght){
callback(tmpArray);
}
});
});

Answer

Asynchronous code strikes again! fs.readdir() is asynchronous. Your callback method is called separate from the execution of fs.readdir(). That's why your tmpArray is empty when you log it in your callback method curDirReadFinn().

There are some ways to fix your problem:

  1. Ready your directory and files synchronously. NodeJS has methods for that. See here: https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options

  2. As @Thomas mentioned, you can make use of stat and isFile() to get it over with faster. In general eliminate the need for heavy asynchronous code.

  3. Use Promises!