Il y a essentiellement deux façons d'y parvenir. Dans un environnement asynchrone, vous remarquerez qu'il y a deux types de boucles : série et parallèle. Une boucle série attend la fin d'une itération avant de passer à l'itération suivante, ce qui garantit que chaque itération de la boucle se termine dans l'ordre. Dans une boucle parallèle, toutes les itérations sont lancées en même temps et l'une d'entre elles peut se terminer avant l'autre. Dans ce cas, il est donc probablement préférable d'utiliser une boucle parallèle, car l'ordre dans lequel la marche se termine n'a pas d'importance, du moment qu'elle se termine et renvoie les résultats (sauf si vous les voulez dans l'ordre).
Une boucle parallèle ressemblerait à ceci :
var fs = require('fs');
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, results);
list.forEach(function(file) {
file = dir + '/' + file;
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
};
Une boucle en série ressemblerait à ceci :
var fs = require('fs');
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err) return done(err);
var i = 0;
(function next() {
var file = list[i++];
if (!file) return done(null, results);
file = dir + '/' + file;
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
next();
});
} else {
results.push(file);
next();
}
});
})();
});
};
Et pour le tester sur votre répertoire personnel (ATTENTION : la liste des résultats sera énorme si vous avez beaucoup de choses dans votre répertoire personnel) :
walk(process.env.HOME, function(err, results) {
if (err) throw err;
console.log(results);
});
EDIT : Amélioration des exemples.