我正在尝试编写一种方法来查找文件夹中的所有文件,包括子文件夹。使用fs.readdirSync
编写非常简单,但是我正在尝试编写一个不会阻塞的版本。 (即使用fs.readdir
)。
我有一个可以使用的版本,但它并不漂亮。能对节点有更多经验的人可以看看是否有更好的方式编写此代码吗?我可以在代码库中看到其他一些可以应用此模式的地方,所以拥有一个更干净的版本会很不错!
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
}
答案 0 :(得分:3)
我会做些事情来使它更清洁:
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];
}
}