我知道 io-q,它是一个执行异步 IO 的库,从而产生了 Promise。但我正在寻找一个使用Q库递归遍历目录结构的简单示例,其中最终结果是所有目录中所有文件的列表,这些文件从提供给某个函数的文件夹开始,但在过程中被展平到单个文件名数组。
有这样的例子吗?或者也许有一个不是递归的例子,这很好。我猜这很简单,但这是我第一次接触异步/承诺。
我知道 io-q,它是一个执行异步 IO 的库,从而产生了 Promise。但我正在寻找一个使用Q库递归遍历目录结构的简单示例,其中最终结果是所有目录中所有文件的列表,这些文件从提供给某个函数的文件夹开始,但在过程中被展平到单个文件名数组。
有这样的例子吗?或者也许有一个不是递归的例子,这很好。我猜这很简单,但这是我第一次接触异步/承诺。
我发现这个要点可以满足您的需求并且很容易承诺:
var Q = require('q'),
fs = require('fs'),
p = require('path');
function readDir(path) {
return Q.nfcall(fs.lstat, path).then(function(stat) {
if (stat.isDirectory()) {
return Q.nfcall(fs.readdir, path).then(function(files) {
return Q.all(files
// .map(p.join.bind(p, path)).map(readDir)
.map(function(file) {
return readDir(p.join(path, file));
})
).then(
// Function.apply.bind(Array.prototype.concat, [])
function(results) {
return [].concat.apply([], results);
});
});
} else {
return [path];
}
});
}
好吧,这就是我最终得出的解决方案(CoffeeScript)。我不是 Node 或 Q 专家,所以我想现在就可以了。我的解决方案实际上是扁平化列表,从输出中删除目录的方法是.then()
删除read(f)
.
Q = require('q')
fs = require('fs')
_ = require("lodash")
isFile = (name) ->
fs.statSync(name).isFile()
withDir = (dir) ->
(files) -> _.map(files, (f) -> "#{dir}/#{f}")
read = (dir) ->
Q.nfcall(fs.readdir, dir)
.then(withDir dir)
.then((files) -> Q.all(toPromises files))
toPromises = (files) ->
for f in files
if isFile f then Q(f) else read(f).then((m) -> m.concat("d " + f))
read("my-root-dir")
.then((files) -> _.flatten(files))
.then((r) -> console.log r)
Q-IO的listTree
功能完全符合您的要求,因此您可以查看实现。