我正在尝试编写一种方法来查找文件夹中的所有文件,包括子文件夹。使用 fs.readdirSync 编写非常简单,但我正在尝试编写一个不会阻塞的版本。 (即使用fs.readdir
)。
我有一个可以运行的版本,但不太漂亮。对 Node 有更多经验的人可以看看是否有更好的方法来编写这个?我可以在我的代码库中看到其他一些地方可以应用此模式,因此如果有一个更干净的版本就好了!
private static findFilesFromFolder(folder: string): Promise<string[]> {
let lstat = util.promisify(fs.lstat)
let readdir = util.promisify(fs.readdir)
// Read the initial folder
let files = readdir(folder)
// Join the folder name to the file name to make it absolute
.then(files => files.map(file => path.join(folder, file)))
// Get the stats for each file (also as a promise)
.then(files =>
Promise.all(files.map(file =>
lstat(file).then(stats => { return { file: file, stats: stats } })
))
)
// If the file is a folder, recurse. Otherwise just return the file itself.
.then(info =>
Promise.all(info.map(info => {
if (info.stats.isDirectory()) {
return this.findFilesFromFolder(info.file)
} else {
return Promise.resolve([info.file])
}
}
)))
// Do sume munging of the types - convert Promise<string[][]> to Promise<string[]>
.then(nested => Array.prototype.concat.apply([], nested) as string[])
return files
}
最佳答案
我会做一些事情来使其更干净:
- 将递归基本情况从循环内移动到顶层
- 使用
async
/await
语法 - 使用
const
代替let
还将 promisify
调用放入 import
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];
}
}
关于node.js - 有没有更好的方法在 typescript 中编写这个递归方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59267003/