Цей використовує максимальну кількість нових функцій мовлення, доступних у вузлі 8, включаючи Обіцянки, утиліта / промальовування, руйнування, асинхрон-чекайте, карта + зменшення та інше, змушуючи ваших колег почухати голову, намагаючись зрозуміти, що триває.
Вузол 8+
Ніяких зовнішніх залежностей.
const { promisify } = require('util');
const { resolve } = require('path');
const fs = require('fs');
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
async function getFiles(dir) {
const subdirs = await readdir(dir);
const files = await Promise.all(subdirs.map(async (subdir) => {
const res = resolve(dir, subdir);
return (await stat(res)).isDirectory() ? getFiles(res) : res;
}));
return files.reduce((a, f) => a.concat(f), []);
}
Використання
getFiles(__dirname)
.then(files => console.log(files))
.catch(e => console.error(e));
Вузол 10.10+
Оновлено для вузла 10+ з ще більшою кількістю whizbang:
const { resolve } = require('path');
const { readdir } = require('fs').promises;
async function getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
const files = await Promise.all(dirents.map((dirent) => {
const res = resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
}));
return Array.prototype.concat(...files);
}
Зауважте, що починаючи з вузла 11.15.0, ви можете використовувати files.flat()
замість того, Array.prototype.concat(...files)
щоб вирівняти масив файлів.
Вузол 11+
Якщо ви хочете повністю підірвати голову вгору, ви можете використовувати наступну версію, використовуючи ітератори асинхронізації . Окрім того, що він справді крутий, він також дозволяє споживачам одночасно витягувати результати, що робить його більш підходящим для дійсно великих каталогів.
const { resolve } = require('path');
const { readdir } = require('fs').promises;
async function* getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
const res = resolve(dir, dirent.name);
if (dirent.isDirectory()) {
yield* getFiles(res);
} else {
yield res;
}
}
}
Використання змінилося, тому що тип повернення тепер є ітератором асинхронізації замість обіцянки
(async () => {
for await (const f of getFiles('.')) {
console.log(f);
}
})()
Якщо когось цікавить, я написав більше про ітератори асинхронізації тут: https://qwtel.com/posts/software/async-generators-in-the-wild/