Запрос в mongoose с вложенным вторым запросом
Здравствует, имеется код для записи в эксель таблицу (библиотека exceljs):
Value.find({ enterpriseId: req.params.id })
.then((el) => {
const workbook = new Excel.Workbook();
const sheet = workbook.addWorksheet('sheet');
let i = 1;
const arr = [];
el.forEach((item) => {
if (!arr.some((u) => u === item.num)) {
arr.push(item.num);
}
});
sheet.autoFilter = 'A1:AZ1';
arr.forEach((u) => {
el.filter((f) => f.num === u).forEach((value, index) => {
if (index === 0 && value.proff) {
Proff767.find({ proff: value.proff }).then((s) => {
s.forEach((SIZ) => {
sheet.addRow(SIZ);
});
}).catch((e) => next(e));
}
value.number = i;
sheet.addRow(value);
i += 1;
});
});
Проблема в том, что данные из запроса Proff767.find находящиеся в блоке then() приходят после завершения основного цикла и запись в таблицу не происходит, где я ошибся?
Ответы (1 шт):
Автор решения: Ruslan
→ Ссылка
Проблема заключается в том, что вы работаете с асинхронными операциями в цикле, и метод Proff767.find
возвращает ПРОМИС, который выполняется АСИНХРОННО. В результате все промисы, созданные в цикле, выполняются в фоновом режиме, а основной поток кода продолжает выполнение и завершает работу цикла, не дожидаясь результата этих промисов.
Для этого можно использовать async/await вместе с Promise.all.
Value.find({ enterpriseId: req.params.id })
.then(async (el) => {
const workbook = new Excel.Workbook();
const sheet = workbook.addWorksheet('sheet');
let i = 1;
const arr = [];
el.forEach((item) => {
if (!arr.some((u) => u === item.num)) {
arr.push(item.num);
}
});
sheet.autoFilter = 'A1:AZ1';
const proffPromises = [];
arr.forEach((u) => {
const filteredValues = el.filter((f) => f.num === u);
filteredValues.forEach((value, index) => {
if (index === 0 && value.proff) {
const proffPromise = Proff767.find({ proff: value.proff }).then((s) => {
s.forEach((SIZ) => {
sheet.addRow(SIZ);
});
});
proffPromises.push(proffPromise);
}
value.number = i;
sheet.addRow(value);
i += 1;
});
});
// Дождаться выполнения всех асинхронных запросов к базе данных
await Promise.all(proffPromises);
// Сохранение Excel файла или дальнейшие действия
})
.catch((e) => next(e));