我正在编写一个NodeJS模块,它从Dropbox复制一堆文件夹,并根据文件夹结构创建一个目录。令我头疼的部分是我需要获取主目录中所有文件夹的名称,然后获取文件夹中所有文件的名称,然后再转到下一个函数。
现在是我的流程:
和一些伪代码:
function getListOfFiles() {
var subfolders = [];
var fileNames = [];
dbClient.readdir('', function(error, folders) {
folders.forEach(function(folder, index) {
subfolders.push(folder);
dbClient.readdir('/'+folder, function(error, subfolders) {
subfolders.forEach(function(subfolder, index) {
dbClient.readdir('/'+folder+'/'+subfolder, function(error, files) {
files.forEach(function(file, index) {
if (isMarkdownFile) {
fileNames.push(file)
}
});
});
});
});
}
});
return fileNames;
}
我已经研究了一些似乎应该解决这个问题的软件包,以及JS Generators,但我不确定最简单的解决方案应该是什么。我的代码在Node 0.11.3上运行正常,因此生成器是一个选项,但这对我来说是一个新概念,我似乎无法找到与我匹配的示例。
答案 0 :(得分:1)
使用async package。具体而言,循环的each
,eachSeries
或eachLimit
以及控制流的waterfall
和series
。
我建议您阅读each
函数的每一个......以确定哪种函数对您的情况有效且一致/可靠。
function getListOfFiles(callback) {
async.waterfall([
// get a list of the top level folders
function (cb) {
dbClient.readdir('', function (error, topLevelFolders) {
if (error) return cb(error);
cb(null, topLevelFolders); // pass the folders to the next function (this is the "waterfall")
});
},
// get an array of all topLevel/subFolders combos
function (topLevelFolders, cb) {
var everySubFolder = [];
async.each(topLevelFolders, function (folder, subFolderCallback) {
dbClient.readdir(folder, function (error, subFolders) {
if (error) return subFolderCallback(error);
everySubFolder = everySubFolder.concat(subFolders);
});
}, function (error) {
if (error) return cb(error);
cb(null, everySubFolder); // pass all the folder/subfolder combos to the next function
});
},
// get an array of all the files in each folder/subfolder
function (everySubfolder, cb) {
var fileNames = [];
async.each(everySubFolder, function (folder, fileNameCallback) {
dbClient.readdir(folder, function (error, files) {
if (error) return fileNameCallback(error);
fileNames = fileNames.concat(files);
fileNameCallback();
});
}, function (error) {
if (error) return cb(error);
cb(null, fileNames); // pass every file combo to the waterfall callback function
});
}
], function (error, fileNames) {
if (error) return callback(error);
callback(null, fileNames); // all done! Every file combo goes the function's callback!
});
}
当您使用它时,您将:
getListOfFiles(function (err, files) {
// Voila! here are all your files
});
明确添加.each
错误处理。如果它在循环期间碰到错误,它将在没有循环的情况下继续循环。其中,依赖文件的数量可能会有一段时间。