等待递归 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 函数结束的主要内容,如果未能解决你的问题,请参考以下文章