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
ingfs
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
只被调用一次,而不是通过每个方法调用。哦,当然,它是递归的!真是个小学生的错误,我今天过得不愉快!不仅是由于递归,而且当您从外部多次调用您的方法时也是如此。诚然,