Reputation: 4025
The below code builds a dictionary (associative array) of the files in a folder, skipping directories and hidden (.*) files. The coe works because the console.log(file_dict)
shows the dictionary before being returned. However, when I call the get_files
function, the return value from return file_dict
is undefined
I'm pretty sure this problem is because readdir
is async. So, I need to switch, to readdirSync
. BUT conceptually I'm not getting why the returned value in the async version is undefined.
What am I missing?
file-explorer.js
var fs = require('fs');
var get_files = function() {
fs.readdir(__dirname + '/content/', function (err, files) {
if (!files.length) {
return console.log(' \033[31m No files to show\033[39m\n');
}
// called for each file walked in the directory
var file_dict = {};
var file_index = 0;
function file(i) {
var filename = files[i];
fs.stat(__dirname + '/' + filename, function (err, stat) {
if (stat.isDirectory() || filename[0] == '.' ) {
// do nothing, skip these dictionaries and dot files
} else {
++file_index;
file_dict[file_index] = filename;
};
if (++i == files.length) {
console.log('right before returning');
console.log(file_dict);
return file_dict;
} else {
// continue getting files
file(i);
};
});
}
file(0);
});
}
console.log ( get_files() ); // returns undefined
Thanks.
Upvotes: 2
Views: 9007
Reputation: 74655
Asynchronous functions don't return. They call their callback with their return value.
Consider:
var get_files = function (cb) {
fs.readdir(__dirname + '/content/', function (err, files) {
if (!files.length) {
return console.log(' \033[31m No files to show\033[39m\n');
}
// called for each file walked in the directory
var file_dict = {};
var file_index = 0;
function file(i) {
var filename = files[i];
fs.stat(__dirname + '/' + filename, function (err, stat) {
if (stat.isDirectory() || filename[0] == '.') {
// do nothing, skip these dictionaries and dot files
} else {
++file_index;
file_dict[file_index] = filename;
};
if (++i == files.length) {
console.log('right before returning');
console.log(file_dict);
return cb(file_dict);
} else {
// continue getting files
return file(i);
};
});
}
return file(0);
});
}
get_files(function (v) { console.log(v); });
Upvotes: 7