@angelzzz

Как вызывать mongoose findOne внутри forEach дожидаясь ответа?

У меня есть массив, я перебираю его с помощью forEach и проверяю тип (type ) каждого значения. Для одного типа мне нужно делать запрос к mongoDB, дождаться ответа и только потом идти дальше по массиву.

Если это имеет значение - я дальше использую эти значения и результат для вызова socket.io emit внутри setTimeOut.

Вот пример перебора:

questionList.forEach((question) => {
    let respName = "";
    let respObj = question;

    if (question.type === "some_type") {
      // some not important code
      // respName = "some_name" 
    } else if (question.type === "some_typeN") {
      // some not important code
      // respName = "some_nameN"
    } else if (question.type === "some_type4") {
      respName = "some_name4"
      respObj = getBlockStats(handle, block);
    } else {
      // some not important code
      // respName = "some_nameX"
    }

    setTimeout(() => {
      io.emit(respName, respObj);
    }, offset);

    offset += offsetIncrease;
});


Вот функция которую я вызываю для обращения к базе:

const getBlockStats = (handle, block) => {
  return GameAnswers.findOne({ handle })
    .then(gameAnswers => {
      let maxQuesstionInBlock = gameAnswers.answers
        .reduce((a, b) => {
          return (parseInt(a.ownId) > parseInt(b.ownId) ? a : b)
        })
      let results = [];

      for (let i = 1; i <= maxQuesstionInBlock.ownId; i++) {
        let team1AllAnswers = gameAnswers.answers
          .filter(el => el.blockId === block)
          .filter((el) => el.team === "team1")
          .filter((el) => parseInt(el.ownId) === i);

        let team1CorrectAnswers = team1AllAnswers
          .filter(el => el.correct === "true");

        let team2AllAnswers = gameAnswers.answers
          .filter(el => el.blockId === block)
          .filter((el) => el.team === "team2")
          .filter((el) => parseInt(el.ownId) === i);

        let team2CorrectAnswers = team2AllAnswers
          .filter(el => el.correct === "true");

        let result = {
          "question": i,
          "team1": {
            "all": team1AllAnswers.length,
            "correct": team1CorrectAnswers.length,
            "percent": team1CorrectAnswers.length * 100 / team1AllAnswers.length
          },
          "team2": {
            "all": team2AllAnswers.length,
            "correct": team2CorrectAnswers.length,
            "percent": team2CorrectAnswers.length * 100 / team2AllAnswers.length
          }
        }

        results.push(result);

      }
      return results;
    })
    .catch(err => {
      console.log("no GameAnswers find err -> ", err);
    });
}


По логам я вижу, что мой запрос к mongoDB происходит после того как forEach пройдет через вес массив. Для for some_type4 значение respObj равно пустому объекту.
  • Вопрос задан
  • 168 просмотров
Решения вопроса 1
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы