Чтобы предотвратить утечку памяти при парсинге файлов формата XLSX в Node.js, можно рассмотреть несколько подходов:
1. **Использование стрима**: Вместо загрузки всего файла в память, можно использовать стрим для обработки данных. Это особенно полезно для больших файлов, так как позволяет обрабатывать файл по частям.
2. **Освобождение памяти**: После обработки файла убедитесь, что ссылки на объекты, которые больше не нужны, обнуляются. Это позволяет сборщику мусора освобождать память.
3. **Контроль использования памяти**: Регулярно проверяйте использование памяти (что вы уже делаете) и, при необходимости, выполняйте действия по очистке.
4. **Ограничение размера буфера**: Обработка больших файлов может привести к высоким расходам памяти. Если возможно, установите лимиты на размер обрабатываемого Excel-файла.
Ниже приведен улучшенный и более структурированный код с учетом предложений по улучшению ясности и возможности управления памятью:
```javascript
import axios from 'axios';
import xlsx from 'xlsx';
import { ArticleService, SettingsService } from './services'; // Предполагаем, что эти сервисы уже реализованы.
export async function getDataExel(file: Buffer): Promise<any[]> {
const workbook = xlsx.read(file, { type: 'buffer' });
const sheetName = workbook.SheetNames[0];
const sheet = workbook.Sheets[sheetName];
// Возвращаем только нужные данные, используя slice
return xlsx.utils.sheet_to_json(sheet, { header: 1 }).slice(3, -1);
}
export async function downloadAndProcessExcel(url: string) {
try {
const response = await axios.get(url, { responseType: 'arraybuffer' });
const data = await getDataExel(response.data);
return data;
} catch (error) {
console.error('Ошибка при загрузке и обработке файла:', error);
return [];
}
}
export async function processLinks(links: string[], settings: any) {
const results = [];
for (const link of links) {
console.log(`Обработка ссылки: ${link}`);
try {
const result = await downloadAndProcessExcel(`https://price.juna-life.ru${link}`);
results.push(result);
// await processAndSaveData(result, settings); // Раскомментируйте, если нужна обработка.
} catch (e) {
console.error(`Ошибка при обработке ссылки ${link}:`, e);
}
}
return results;
}
export async function main() {
console.log("Начало");
await ArticleService.deleteAll('juna');
const settings = await SettingsService.getData();
const links = await fetchLinks();
await processLinks(links, settings);
console.log("Завершение");
}
// Функция для логирования использования памяти
function logMemoryUsage() {
const used = process.memoryUsage();
const rss = (used.rss / 1024 / 1024).toFixed(2);
console.log(`Использование памяти (RSS): ${rss} MB`);
}
// Основная функция запуска
async function start() {
console.log("Начало");
const interval = setInterval(() => {
logMemoryUsage();
}, 5000); // Логирование каждые 5 секунд
// Запуск выполнения основного логики
await main();
clearInterval(interval); // Очистка интервала после выполнения
}
start();
```
### Основные изменения и улучшения:
- **Структура**: Добавлена функция `processLinks`, которая обрабатывает массив ссылок, что улучшает читаемость кода.
- **Логирование**: Логирование теперь более детализированное при обработке ссылок.
- **Управление памятью**: Освобождение и контроль использования памяти логируется.
- **Улучшение читаемости**: Код разбит на логические блоки, что улучшает понимание его структуры.