使用bluebird递归迭代目录

Eya*_*nik 3 recursion node.js promise typescript bluebird

我正在尝试使用Node和Bluebird(promises库)递归迭代一个给定的目录,但只要看起来它不能正常工作.

当我取消注释下面的'console.log'行时,似乎我得到了正确的结果,但我不确定是怎么回事,因为我从下面的消费代码得到的最终结果只是第一个文件第一个目录.

也许问题不在于迭代函数本身,而在于我正在消费它的方式.

我对承诺有点新意,所以也许我只是以错误的方式接近它.

这是我写的代码.

import * as Path from "path";
import * as Promise from "bluebird";
const FS: any = Promise.promisifyAll<any>((require("fs")));
export class Dir {
  public static iterate(path: string) {
    return new Promise((resolve, reject) => {
      FS.lstatAsync(path).then(stat => {
        if (stat.isDirectory()) {
          FS.readdirAsync(path).each(name => {
            let fullPath = Path.join(path, name);
            // console.log(fullPath);
            FS.lstatAsync(fullPath).then(stat => stat.isDirectory() ? Dir.iterate(fullPath) : resolve(fullPath));
          });
        } else {
          reject(`The path '${path}' is not a directory.`)
        }
      });
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我使用/消费它的方式

Dir.iterate(ProjectPaths.client)
.then(f => {
    console.log(f)
    return f;
})
.catch(e => console.log(e));
Run Code Online (Sandbox Code Playgroud)

编辑:只是为了澄清我正在使用TypeScript!忘了在我的帖子中提到它.

Ben*_*aum 5

基于Petka在bluebird API文档中的代码,这是一个使用bluebird递归迭代目录的带注释的示例:

function readDir(dirName) { // reading a directory requires its name
    return fs.readdirAsync(dirName).map(fileName => { // for each file we take it
        var path = Path.join(dirName, fileName); // get the correct path
        // if it's a directory we scan it too recursively, otherwise we just add it
        return fs.statAsync(path).then(stat => stat.isDirectory() ? readDir(path) : path);
    }).reduce((a, b) => a.concat(b), []); // we flatten the result to an array
}
Run Code Online (Sandbox Code Playgroud)

或者更"聪明"的ES2015风格:

const readDir => dirName => fs.readdirAsync(dirName).map(fileName => { 
        var path = Path.join(dirName, fileName); 
        return fs.statAsync(path).then(stat => stat.isDirectory() ? readDir(path) : path);
    }).reduce((a, b) => a.concat(b), []);
Run Code Online (Sandbox Code Playgroud)

没有必要将明确的结构作为承诺链.您的尝试失败是因为您正在解决每个内部文件上的外部承诺,承诺只解析一次.