等待递归 readdir 函数结束

Posted

技术标签:

【中文标题】等待递归 readdir 函数结束【英文标题】:Waiting for the end of a recursive readdir function 【发布时间】:2015-07-27 16:20:00 【问题描述】:

我正在使用递归 readdir 读取目录的整个文件树以将其放入数据库。

我的问题是我试图停止下一行代码,而整个 readdir/insert 到数据库还没有完成。

我一直在寻找承诺中的解决方案,但在第一次调用我的函数时(所以在树的第一个文件夹中),承诺就实现了......

有什么想法吗?

function readsousdir(path, db, db2) 
    var Datastore = require('nedb');
    var fs = require('fs');
    fs.readdir(path + '\\', function (err, files) 
        files.forEach(function (file) 
            fs.stat(path + '\\' + file, function (err, stats) 
                var foldertrue = stats.isDirectory();
                var filetrue = stats.isFile() == true;
                if (foldertrue == true) 
                    var doc;
                    doc = folderdb(path + '\\' + file);
                    db2.insert(doc);
                    readsousdir(path + '\\' + file, db, db2);
                
                if (filetrue) 
                    doc = pistedb(path + '\\' + file, []);
                    db.insert(doc);

                
            );
        );
    );

【问题讨论】:

db 对象来自什么类型的对象? 这是一个 nedb 数据存储:github.com/louischatriot/nedb 你使用的是什么承诺库? 我可以使用 Q 或 bluebird,例如您使用 bluebird,我也会使用它。你们都太他妈快了! (比我更多,我试图理解你所有的答案)。非常感谢您的帮助。 【参考方案1】:

使用 BlueBird,您可以使用 reduce

var fs = Promise.promisifyAll(require("fs"));

function readsousdir(path, db, db2) 
    var Datastore = require('nedb');
    return fs.readdirAsync(path + '\\').reduce(function(_, file)
        return fs.statAsync(path + '\\' + file)
        .then(function(stats)
            var foldertrue = stats.isDirectory();
            var filetrue = stats.isFile() == true;
            if (foldertrue == true) 
                var doc;
                doc = folderdb(path + '\\' + file);
                db2.insert(doc);
                return readsousdir(path + '\\' + file, db, db2)
            
            if (filetrue) 
                doc = pistedb(path + '\\' + file, []);
                db.insert(doc);
            
        );
    );

假设你的 db 库返回 Promise 并且你想等待插入,你会这样做

function readsousdir(path, db, db2) 
    var Datastore = require('nedb');
    return fs.readdirAsync(path + '\\').reduce(function(_, file)
        return fs.statAsync(path + '\\' + file)
        .then(function(stats)
            var foldertrue = stats.isDirectory();
            var filetrue = stats.isFile() == true;
            if (foldertrue == true) 
                var doc;
                doc = folderdb(path + '\\' + file);
                return db2.insert(doc).then(function()
                    return readsousdir(path + '\\' + file, db, db2)
                );
            
            if (filetrue) 
                doc = pistedb(path + '\\' + file, []);
                return db.insert(doc);
            
        );
    );

【讨论】:

如果您使用的是 Bluebird,为什么不承诺 fs.readdir() 而不是使用回调? 正如您的评论所表明的,这段代码真的不应该做fs.statSync()。那应该是异步的。而且,我知道这不是问题的一部分,但我怀疑 db.insert(doc)db2.insert(doc) 可能需要适当的错误处理,这肯定会增加完整解决方案的复杂性。 @jfriend00 我没有立即注意到对 stat 的调用,所以我在中间更改了策略... 未处理的拒绝错误:ENOENT:没有这样的文件或目录,在错误(本机)处统计 'D:\A ECOUTER\undefined' 它似乎在第一个循环中丢失了“文件”(未定义),错误的 javascript 文件是这个:bluebird\js\main\captured_trace.js:478

以上是关于等待递归 readdir 函数结束的主要内容,如果未能解决你的问题,请参考以下文章

Node.js fs.readdir 递归目录搜索

Node.js fs.readdir 递归目录搜索

我可以等待 fs.readdir 但我不知道为啥

fs.readdir 递归搜索深度=1

递归的使用:遍历目录函数

大家来来一个小递归函数删除目录!!!!!