Node.js 使用bluebird递归迭代目录

Node.js 使用bluebird递归迭代目录,node.js,recursion,typescript,promise,bluebird,Node.js,Recursion,Typescript,Promise,Bluebird,我试图使用Node和Bluebird(Promissions库)递归地迭代给定的目录,但它似乎不能正常工作 当我取消注释下面的“console.log”行时,似乎我得到了正确的结果,但我不确定发生了什么,因为我从下面的消费代码得到的最终结果只是第一个目录中的第一个文件 也许问题不在于迭代函数本身,而在于我使用它的方式 我对承诺有点陌生,所以也许我只是用错误的方式来实现它 这是我写的代码。 import * as Path from "path"; import * as Promise from

我试图使用Node和Bluebird(Promissions库)递归地迭代给定的目录,但它似乎不能正常工作

当我取消注释下面的“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.`)
        }
      });
    })
  }
}

编辑:只是为了澄清我使用的是打字脚本!忘了在我的帖子中提到它。

根据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
}
或者更“聪明”的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), []);

没有必要像承诺链一样。您的尝试失败,因为您正在解析每个内部文件上的外部承诺,承诺只解析一次

您希望的函数输出是什么?看起来您正在尝试递归迭代,但最终只使用一条路径进行解析。而且,您没有返回任何内部承诺,因此代码没有等待它们。嗯,我想在使用者处获取所有文件和目录,以便我可以对其进行一些操作,例如重命名或删除文件/目录。嘿,您的代码具有[显式构造反模式](stackoverflow.com/questions/23803743/what-is-explicit-promise-construction-antipattern-and-how-do-i-avoid-it),bluebird实际上在这里包含了一个迭代目录的示例:好的,一切都正常,但是我应该如何处理需要抛出错误的情况?你能给出一个示例吗?就像在我给出的示例中,我使用了reject,我应该使用}else{throw…}就像我通常会做的那样?或者在bluebird中有更好的方法来做吗?@jfriend00我在使用TypeScript,我已经更新了我的OP并做了一个关于它的说明,谢谢!:)你应该像平常一样抛出-承诺会有错误传播:)
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), []);