Асинхронно на async/await
const { promises: fs } = require('fs');
const path = require('path');
const bot = {
command: (cmd, cb) => cb({ctx: 'ctx'})
};
bot.command('/report', (ctx) => {
fullyReportGenerator()
.then((reportRawData) => {
console.log(reportRawData);
console.log(ctx);
})
.catch(console.error);
});
async function fullyReportGenerator() {
const reportDirectoryPath = path.join(__dirname, '../reports');
const reportFiles = await readDir(reportDirectoryPath);
const reportData = [];
for (const filePath of reportFiles) {
const reportRawDataItem = await readFile(filePath);
if (typeof reportRawDataItem === 'object' && 'content' in reportRawDataItem) {
reportData.push(reportRawDataItem.content);
}
}
return reportData;
}
async function readDir(dirPath) {
const files = await fs.readdir(dirPath);
return files.map((x) => path.join(dirPath, x));
}
async function readFile(filePath) {
const data = await fs.readFile(filePath, {encoding: 'utf-8'});
try {
const json = JSON.parse(data);
return json;
} catch (err) {
console.error(err);
}
return data;
}
Приведённый код является не более чем иллюстрацией подхода к решению задачи или решением для небольшого количества небольших отчётов.
Не учитывает, что в каталоге report могут быть подкаталоги (решается проверками и рекурсивным вызовом readDir).
Чтение файлов происходит последовательно, но при большом количестве файлов нужно распараллелить (я использую p-queue).
Не оптимально с тз производительности, если файлы отчётов большого размера, но можно уйти на стримы.
Полностью синхронный
На небольших количествах файлов и небольших данных будет, скорее всего, работать быстрее.
const fs = require('fs');
const path = require('path');
const bot = {
command: (cmd, cb) => cb({ctx: 'ctx'})
};
bot.command('/report', (ctx) => {
const reportRawData = fullyReportGenerator();
console.log(reportRawData);
console.log(ctx);
});
function fullyReportGenerator() {
const reportDirectoryPath = path.join(__dirname, '../reports');
const reportFiles = readDir(reportDirectoryPath);
const reportData = [];
for (const filePath of reportFiles) {
const reportRawDataItem = readFile(filePath);
if (typeof reportRawDataItem === 'object' && 'content' in reportRawDataItem) {
reportData.push(reportRawDataItem.content);
}
}
return reportData;
}
function readDir(dirPath) {
const files = fs.readdirSync(dirPath);
return files.map((x) => path.join(dirPath, x));
}
function readFile(filePath) {
const data = fs.readFileSync(filePath, {encoding: 'utf-8'});
try {
const json = JSON.parse(data);
return json;
} catch (err) {
console.error(err);
}
return data;
}
fs.readdir()не возвращает промис, поэтомуawaitтут бесполезен. Как вариант, используйтеfs-extraвместоfs. – Yaant Sep 17 '20 at 12:27fsдобавили нативную поддержку промисов. Просто у нас тут проект базируется на 8 ноде, а там такого не было. :) – Yaant Sep 17 '20 at 12:50