Код цикла ForEach не работает в promises при использовании mongoose

#javascript #node.js

#javascript #node.js

Вопрос:

все! Я новичок в NodeJS. Недавно я работал над проектом, который требует, чтобы я вводил в массив определенные значения. Написанный мной код не работает, и я предполагаю, что это связано с promises. Это мой код:

 router.get('/dashboard/misTalleres', ensureAuthenticated, (req, res) => {
  let misTalleres = req.user.talleres;
  let arrayTalleres = [];
  misTalleres.forEach((taller) => {
    Taller.findOne({_id: taller})
      .then((tallerFound) => {
        arrayTalleres.push(tallerFound);
      })
      .catch(err => console.log(err));
  });

  console.log(arrayTalleres);
  // console.log(arrayTalleres);
  res.render('misTalleres', { name: req.user.name })

});  

Мне нужно ввести в arrayTalleres возвращаемые значения из более высокого файла.findOne.

Спасибо за любую помощь в расширенном! Том.

Комментарии:

1. Я предполагаю, что Taller.findOne это асинхронная функция. console.log(arrayTalleres) , скорее всего, вызывается до возврата асинхронной функции.

2. @DPac then — это метод promise, который гарантированно выполняет свой обратный вызов асинхронно

3. @Bergi Приведенный выше код вызывается console.log(arrayTalleres) извне then . В это время массив, вероятно, все еще пуст.

4. @DPac s/probably/definitely

Ответ №1:

Используйте Promise.all (и избегайте forEach ):

 let misTalleres = req.user.talleres;
Promise.all(misTalleres.map(taller => {
  return Taller.findOne({_id: taller});
})).then(arrayTalleres => {
  console.log(arrayTalleres);
  res.render('misTalleres', { name: req.user.name })
}, err => {
  console.log(err);
});
  

Комментарии:

1. Большое вам спасибо!

Ответ №2:

Я рекомендую вам использовать Promise.all .

Шаги:

  1. Создайте список обещаний
  2. Передайте этот список в Promise.all
  3. Подождите, пока Promise.all разрешится

Код:

 router.get('/dashboard/misTalleres', ensureAuthenticated, (req, res) => {
  const misTalleres = req.user.talleres;

  // list of promises
  const promise_array = misTalleres.map((taller) => Taller.findOne({ _id: taller }) );

  // execute all promises simultaneaously 
  Promise.all(promise_array).then(arrayTalleres => {
    console.log(arrayTalleres);
    res.render('misTalleres', { name: req.user.name })
  });

});
  

Комментарии:

1. Это тоже было полезно! Спасибо за объяснение!