基本上有两种方法可以实现这一点。在异步环境中,您会注意到有两种循环:串行循环和并行循环。串行循环等待一次迭代完成,然后再进入下一次迭代 - 这保证了循环的每次迭代都按顺序完成。在并行循环中,所有迭代同时开始,并且一个迭代可能在另一个迭代之前完成,但是,它比串行循环快得多。因此,在这种情况下,最好使用并行循环,因为步行完成的顺序并不重要,只要它完成并返回结果即可(除非您希望它们按顺序排列)。
并行循环如下所示:
var fs = require('fs');
var path = require('path');
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 = path.resolve(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);
}
});
});
});
};
串行循环如下所示:
var fs = require('fs');
var path = require('path');
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 = path.resolve(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();
}
});
})();
});
};
并在您的主目录中对其进行测试(警告:如果您的主目录中有很多内容,结果列表将会很大):
walk(process.env.HOME, function(err, results) {
if (err) throw err;
console.log(results);
});
编辑:改进的示例。