如何在两个赋值函数和forEach循环中嵌套一个值?

时间:2014-12-03 20:53:00

标签: javascript node.js asynchronous callback generator

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

现在是我的流程:

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

    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上运行正常,因此生成器是一个选项,但这对我来说是一个新概念,我似乎无法找到与我匹配的示例。

1 个答案:

答案 0 :(得分:1)

使用async package。具体而言,循环的eacheachSerieseachLimit以及控制流的waterfallseries

我建议您阅读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错误处理。如果它在循环期间碰到错误,它将在没有循环的情况下继续循环。其中,依赖文件的数量可能会有一段时间。