是否有一个使用原始Q promise库与节点以异步方式递归遍历目录的示例?

时间:2013-10-14 14:00:28

标签: node.js asynchronous promise

我知道io-q,这个做异步IO的库导致了promises。但我正在寻找一个使用Q库递归遍历目录结构的简单示例,其中最终结果是从提供给某个函数的文件夹开始的所有目录中的所有文件的列表,但在过程中展平到单个文件名数组。

那里有这样的例子吗?或者也许有一个不是递归的例子,这很好。我猜这很简单,但这是我第一次接触到async / promises。

3 个答案:

答案 0 :(得分:4)

我发现this gist可以做你想做的事情并很容易宣传:

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];
        }
    });
}

它使用nfcall来获取文件系统API的承诺,并Q.all在连接它们之前等待所有子目录结果。

答案 1 :(得分:1)

嗯,这是我最终得到的解决方案(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)

答案 2 :(得分:1)

Q-IO中的listTree功能完全符合您的要求,因此您可以查看the implementation