Почему не работает array.push в array.forEach?
Есть следующий код:
hearManager.hear(/^(?:игнорлист)/i, async (context) => {
const all = await users.find();
const usersI = [];
const clubsI = [];
const publicsI = [];
all.forEach(async (element) => {
const resource = await resolveResource({
api: vk.api,
resource: element.id,
});
if (resource.type === "user") {
const [f] = await vk.api.users.get({
user_id: element.id,
});
usersI.push(`\n[id${element.id}|${f.first_name} ${f.last_name}]`);
console.log(usersI);
} else if (resource.type === "club") {
clubsI.push(`\nvk.com/club-${element.id}`);
console.log(clubsI);
} else {
publicsI.push(`\nvk.com/public-${element.id}`);
console.log(publicsI);
}
})
console.log(usersI);
console.log(clubsI);
console.log(publicsI);
});
Что тут вообще происходит?
- Прослушиваем чат.
- Получаем все записи из Mongodb.
- Перебираем все записи.
- Обрабатываем айди и получаем тип страницы (resource.type).
- Разделяем страницы на три типа, собираем из них ссылки и пушим в три пустых массива.
Вывод: внутри forEach всё разделяется и пушится, вне forEach массивы остаются пустыми.
Желаемый результат: три массива с ссылками на пользователя, сообщество, паблик (упоминаниями в случае пользователей).
Ответы (2 шт):
Автор решения: nörbörnën
→ Ссылка
Нельзя так использовать асинхронные вызовы внутри .forEach. .forEach - выполнит последовательно и синхронно свои колбеки и не будет ждать завершения асинхронных задач.
Сделайте так:
for (const element of all) {
const resource = await resolveResource({
api: vk.api,
resource: element.id,
});
if (resource.type === "user") {
const [f] = await vk.api.users.get({
user_id: element.id,
});
usersI.push(`\n[id${element.id}|${f.first_name} ${f.last_name}]`);
console.log(usersI);
} else if (resource.type === "club") {
clubsI.push(`\nvk.com/club-${element.id}`);
console.log(clubsI);
} else {
publicsI.push(`\nvk.com/public-${element.id}`);
console.log(publicsI);
}
}
Автор решения: Aziz Umarov
→ Ссылка
Согласен с предыдущим ответом предложу другой вариант
hearManager.hear(/^(?:игнорлист)/i, async (context) => {
const all = await users.find();
const usersI = [];
const clubsI = [];
const publicsI = [];
await Promise.all(all.map(async (element) => {
const resource = await resolveResource({
api: vk.api,
resource: element.id,
});
if (resource.type === "user") {
const [f] = await vk.api.users.get({
user_id: element.id,
});
usersI.push(`\n[id${element.id}|${f.first_name} ${f.last_name}]`);
console.log(usersI);
} else if (resource.type === "club") {
clubsI.push(`\nvk.com/club-${element.id}`);
console.log(clubsI);
} else {
publicsI.push(`\nvk.com/public-${element.id}`);
console.log(publicsI);
}
}));
console.log(usersI);
console.log(clubsI);
console.log(publicsI);
});
