Возвращается пустой массив, хотя я поместил значения в тот же массив внутри foreach

#javascript #node.js

#javascript #node.js

Вопрос:

Я добавил свой код ниже. Console.log() выводит пустой массив. Кто-нибудь может сказать мне причину??

 var arr = [];
stages.forEach(async(stage) => {
  const tasks = await Task.find({
    stageName: stage._id
  });
  return arr.push(tasks);  
});
console.log(arr);
  

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

1. возвращать значение в forEach бесполезно. Кроме того, find ответ является асинхронным, поэтому вы не можете ожидать, что окончательный журнал консоли (который выполняется синхронно) узнает о значении, которое поступит только в некотором будущем.

2. Подумайте о том, чтобы сделать что-то вроде Promise.all(stages.map(stage => Task.find({stageName: stage._id})))

Ответ №1:

Вы выполняете асинхронность. Массив не будет содержать элементов при console.log запуске. Каждый вызов вашей анонимной функции возвращает обещание, которое вы игнорируете. Если вы хотите убедиться, что у вас есть результаты, вы могли бы сделать это:

 let promises = stages.map(stage => Task.find({
    stageName: stage._id
  }));

Promise.all(promises)
.then(results => {
  console.log(results);
});
  

Ответ №2:

Использование цикла async/await in forEach вам в этом случае не поможет, вместо этого используйте обычный for цикл

 async function execute() {
  var arr = []
  for (let stage of stages) {
    const tasks = await Task.find({
      stageName: stage._id,
    })
    return arr.push(tasks)
  }
  console.log(arr)
}

execute()
  

Ответ №3:

этапы прохождения цикла не выполняются асинхронно перед консолью цикла.журнал напечатает

 const promises = _.map(stages, async (stage) => {
  const tasks = await Task.find({
    stageName: stage._id
  });
  return tasks
})
const tasks = await Promise.all(promises)
  

lodash асинхронная карта возвращает обещание, а разрешение выдает разрешающие данные

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

1. Почему Lodash? В OP это не упоминается.

2. Вы можете просто вернуться Task.find({...}) из своей функции map, поскольку ожидание обещания, а затем возврат результата из асинхронной функции просто снова превратит результат обратно в обещание. Также, возможно, используйте Array.prototype.map() вместо

3. да, действительно, вы можете отобразить с помощью метода array map и создать массив promise. Спасибо

Ответ №4:

Если мое предположение верно,

 async(stage) => {
 const tasks = await Task.find({
  stageName: stage._id
 });
 return arr.push(tasks);  
}  
  

Этот код будет выполнен в следующем цикле событий. таким образом, console.log() выполняется немедленно, таким образом, массив является []
попробуйте войти в систему setTimeout(() => console.log(arr), 1000) или после завершения задачи