【问题标题】:Waiting for the end of a recursive readdir function等待递归 readdir 函数结束
【发布时间】: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,我也会使用它。你们都太他妈快了! (比我更多,我试图理解你所有的答案)。非常感谢您的帮助。

标签: javascript node.js recursion promise 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
猜你喜欢
  • 2019-01-31
  • 2018-01-17
  • 1970-01-01
  • 2017-06-22
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多