I came across a problem when trying to read a directory with Node.js (v8.9.4) in Visual Studio Code. I have a function called readExperiments which runs trough my directory and returns an array of experiments. But somehow the code which comes after the function call is executed first (which results in an "undefined" problem scenario). The console.log statements inside experimentReader.js and the for loop in mustacheModelCreator.js are there for debugging purposes.
Is there a trivial reason why my function is executed afterwards (maybe due to its horrible nesting style) and is there a solution which forces my readExperiments() function to be executed first?
I thank you very much for your help (btw: I am a total javascript beginner).
Code in mustacheModelCreator.js
var experiments = experimentReader.readExperiments();
for(k = 0; k < 1;k++)
{
console.log("Outside experiments: " + experiments[k]);
}
var experimentPaths = experimentReader.getExperimentPaths();
var patients = patientReader.readPatients(experimentPaths);
Code in experimentReader.js:
module.exports.readExperiments = function()
{
var experiments = new Array();
fs.readdir(rootPath, function(err, rootDirectory)
{
if(err) throw err;
for(i = 0; i < rootDirectory.length; i++)
{
console.log("Root Directory: " + rootDirectory[i]);
if(rootDirectory[i]=="resources")
{
var resPath = path.join(rootPath,'/resources');
fs.readdir(resPath, function(err2, resDirectory)
{
console.log("Resources Directory: " + resDirectory[i]);
if(err2) throw err2;
for(j = 0; j < resDirectory.length; j++)
{
if(resDirectory[j] == "results")
{
var resultsPath = path.join(resPath,'/results');
var resultsDirectory;
fs.readdir(resultsPath, function(err3, resultsDirectory)
{
console.log("Results Directory: " + resultsDirectory[i]);
if(err3) throw err3;
for(p = 0; p<resultsDirectory.length;p++)
{
experiments.push(resultsDirectory[p]);
console.log("Inside experiments: " + experiments[p]);
}
});
}
}
});
}
}
});
return experiments;
}
Result:
Outside experiments: undefined
Then the internal console.log statements from readExperiments in experimentReader.js
Your problem lies in the fact that your are using asynchronous functions.
when you say:
fs.readdir(path, function callback(x){} );
your callback
function will be executed at some later point in time, it may be right after the fs.readdir
invocation, or it may be an hour later (usually a few milliseconds though :))
try replacing your usage of readdir
with readdirSync
, see documentation on usage:
https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options
Another alternative would be to use Promise
s or just plain old callbacks and embrace asynchronous nature of node.js
So to sum it up:
experimentReader.readExperiments();
execution continues onto
for(k = 0; k < 1;k++) { console.log("Outside experiments: " + experiments[k]); }
meanwhile code inside your readExperiements
runs, and it so happens that most of the time it finishes after your loop that looks at experiments
array.