Node.js 有没有更好的方法用typescript编写这个递归方法

Node.js 有没有更好的方法用typescript编写这个递归方法,node.js,typescript,recursion,promise,Node.js,Typescript,Recursion,Promise,我正在尝试编写一个方法来查找文件夹中的所有文件,包括子文件夹。使用fs.readdirSync编写非常简单,但我正在尝试编写一个不阻塞的版本。(即使用fs.readdir) 我有一个版本可以用,但不好看。有更多node经验的人可以看看是否有更好的方法来写这个吗?我可以在我的代码库中看到一些其他地方,在那里我可以应用这个模式,所以如果有一个更干净的版本就好了 私有静态FindFileFromFolder(文件夹:字符串):Promise{ 设lstat=util.promisify(fs.lsta

我正在尝试编写一个方法来查找文件夹中的所有文件,包括子文件夹。使用
fs.readdirSync
编写非常简单,但我正在尝试编写一个不阻塞的版本。(即使用
fs.readdir

我有一个版本可以用,但不好看。有更多node经验的人可以看看是否有更好的方法来写这个吗?我可以在我的代码库中看到一些其他地方,在那里我可以应用这个模式,所以如果有一个更干净的版本就好了

私有静态FindFileFromFolder(文件夹:字符串):Promise{
设lstat=util.promisify(fs.lstat)
让readdir=util.promisify(fs.readdir)
//读取初始文件夹
let files=readdir(文件夹)
//将文件夹名称与文件名合并,使其成为绝对名称
.then(files=>files.map(file=>path.join(文件夹,文件)))
//获取每个文件的统计信息(也作为承诺)
。然后(文件=>
Promise.all(files.map)(文件=>
lstat(file).then(stats=>{return{file:file,stats:stats}})
))
)
//如果文件是文件夹,则递归。否则只返回文件本身。
。然后(信息=>
Promise.all(信息地图)(信息=>{
if(info.stats.isDirectory()){
返回此.findFilesFromFolder(info.file)
}否则{
返回Promise.resolve([info.file])
}
}
)))
//是否将承诺转换为承诺
.then(嵌套=>Array.prototype.concat.apply([],嵌套)为字符串[])
返回文件
}

我会做一些事情来让它更干净:

  • 将递归基本情况从循环中移动到顶层
  • 使用
    异步
    /
    等待
    语法
  • 使用
    const
    代替
    let
同时将
promisify
调用放在您的
import
ing
fs

const lstat = util.promisify(fs.lstat)
const readdir = util.promisify(fs.readdir)

…
private static async findFilesFromPath(folder: string): Promise<string[]> {
  const stats = await lstat(folder);
  // If the file is a folder, recurse. Otherwise just return the file itself.
  if (stats.isDirectory()) {
    // Read the initial folder
    const files = await readdir(folder);
    // Join the folder name to the file name to make it absolute
    const paths = files.map(file => path.join(folder, file))
    const nested = await Promise.all(paths.map(p => this.findFilesFromPath(p)))
    // Do sume munging of the types - convert string[][] string[]
    return Array.prototype.concat.apply([], nested) as string[];
  } else {
    return [folder];
  }
}
const lstat=util.promisify(fs.lstat)
const readdir=util.promisify(fs.readdir)
…
私有静态异步findFilesFromPath(文件夹:字符串):承诺{
const stats=wait lstat(文件夹);
//如果文件是文件夹,则递归。否则只返回文件本身。
if(stats.isDirectory()){
//读取初始文件夹
const files=wait readdir(文件夹);
//将文件夹名称与文件名合并,使其成为绝对名称
const path=files.map(file=>path.join(文件夹,文件))
const nested=wait Promise.all(path.map(p=>this.findFilesFromPath(p)))
//对类型执行sume-munging-转换字符串[][]string[]
将Array.prototype.concat.apply([],嵌套)作为字符串[]返回;
}否则{
返回[文件夹];
}
}

当您不在任何地方使用
wait
时,不要将其设置为
async
函数。@Bergi已删除。使用wait,将使reursive代码非常接近同步verison@TitianCernicova-德拉戈米尔:你应该加上这一点作为回答——在我写这篇文章的时候,我完全忘记了使用wait并没有阻止,而是在引擎盖下使用了承诺。你说得对,现在干净多了@deanWombourne我正在努力寻找答案,但使用await转换需要一点时间,这是我错过的关键一点——我(尴尬地)忘记了await并没有阻止,它只是承诺而已。尽管如此,为什么您要将promisify作为一个全局变量而不仅仅放在这个方法中(我在其他任何地方都不使用它们,否则答案是显而易见的!)?@deanWombourne这样,
promisify
只被调用一次,而不是通过每个方法调用。哦,当然,它是递归的!真是个小学生的错误,我今天过得不愉快!不仅是由于递归,而且当您从外部多次调用您的方法时也是如此。诚然,允诺确实缓存了它的结果,所以当你把它放进去时,它不会是一个性能问题,但是我仍然认为它更干净,而且它可以重用模块中的其他地方,即使你还不需要它。哈,我们在那里有所不同,我不会把它移到我需要的时候。(不过,由于递归,我确实需要,哎呀)。promisify缓存很有趣——我不知道。