如何在foreach和wait请求中调用猫鼬findone?

时间:2019-08-20 10:30:18

标签: javascript node.js mongoose

我有一些我用forEach发短信的项目的清单。我检查每个项目的类型,对于一个项目类型,我需要向mongoDB发送请求,并等待响应以进一步使用它。

如果很重要-我使用forEach来使用socket.io发出超时。

这是我现在如何列出清单的方法:

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 => {
            return el.blockId === block
          })
          .filter((el) => {
            return el.team === "team1"
          })
          .filter((el) => {
            return parseInt(el.ownId) === i
          });

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

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

        let team2CorrectAnswers = team2AllAnswers
          .filter(el => {
            return 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在所有列表中生效后才发生。对于some_type4中的respObj,我有一个空对象。我需要在服务器中产生共鸣(例如,请求停止循环并等待结果,之后再继续)

2 个答案:

答案 0 :(得分:0)

最好的解决方案是使用 async / await 处理异步数据库调用,并使用 for..of 循环遍历数组。您无法使用 forEach ,因为异步/等待功能无法在其中使用。

您可以参考this来了解异步/等待。(重点部分 7.2

希望这会有所帮助:)

答案 1 :(得分:0)

这是我使用async / await解决此问题的方式

const questionAction = async (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 = await getBlockStats(handle, block); 
    } else {
      // some not important code
      // respName = "some_nameX"
    }

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

    offset += offsetIncrease;
};

(async () => {
  for (const question of questionList) {
    await questionAction(question);
  }
})()