我如何获得嵌套在两个分配函数和forEach循环内的值?

我正在写一个NodeJS模块,从Dropbox复制一堆文件夹,并根据文件夹结构创build一个目录。 令我头疼的部分是我需要获取主目录中所有文件夹的名称,然后才能获得文件夹中所有文件的名称,然后再转到下一个函数。

这是我现在的过程:

  1. 使用dropboxClient.readdir()获取主目录中的文件夹列表
  2. 遍历文件夹并获取名称子文件夹(再次使用dropboxClient.readdir())
  3. 迭代这些子文件夹并获取文件的名称。
  4. 如果文件是降价文件,请将该名称添加到列表中
  5. 返回子目录中所有降价文件的列表

和一些伪代码:

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发电机,但我不知道最简单的解决scheme应该是什么。 我的代码在节点0.11.3上运行良好,因此生成器是一个选项,但这对我来说是一个新概念,我似乎无法find与我的匹配的示例。

利用asynchronous包 。 具体来说,循环的eacheachSerieseachLimit ,以及用于控制stream的waterfallseries

我build议您阅读eachfunction的eachfunction,以确定哪种function对您的情况有效且一致/可靠。

 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添加.eacherror handling。 如果在循环过程中碰到错误,它将在没有循环的情况下继续循环。 哪一个文件依赖,可能会有一段时间。