简体   繁体   English

在forEach循环中使用异步等待,节点js

[英]Use async await in forEach loop, node js

I had a problem when I tried to use forEach that contained await inside the loop, so I need to define the async in front of the forEach loop and it returned the error.当我尝试在循环中使用包含awaitforEach时遇到问题,因此我需要在forEach循环前面定义async ,它返回了错误。

exports.filterAverageRatingsEachSkillForStudent = async (req, res) => {
  let receiver = req.query.receiver;
  let result = [];
  try {
    console.log('receiver id', receiver);

    for (let id of receiver) {
      console.log('Query String ', id);
      const findRating = await FeedbackSchema.find({
        receiver: id,
        //will add level query later
      }).select('ratingL ratingS ratingR ratingW');
      console.log('Rating Length', findRating.length);
      let totalSpeaking = 0;
      let totalWriting = 0;
      let totalListening = 0;
      let totalReading = 0;
      let lengthS = findRating.length;
      let lengthR = findRating.length;
      let lengthL = findRating.length;
      let lengthW = findRating.length;

      findRating.forEach((rating) => {
        console.log('Speaking star = ', rating.ratingS);
        totalSpeaking += rating.ratingS;
      });
      console.log('Total speaking', totalSpeaking);
      console.log('lengthS = ', lengthS);
      let highestS = lengthS * 5;
      let resultOfSpeakingRate = (totalSpeaking * 5) / highestS;
      console.log('Average Speaking Rate ---> ', resultOfSpeakingRate);

      findRating.forEach((rating) => {
        totalWriting += rating.ratingW;
      });
      let highestW = lengthW * 5;
      let resultOfWritingRate = (totalWriting * 5) / highestW;

      findRating.forEach((rating) => {
        totalReading += rating.ratingR;
      });
      let highestR = lengthR * 5;
      let resultOfReadingRate = (totalReading * 5) / highestR;

      findRating.forEach((rating) => {
        totalListening += rating.ratingL;
      });
      let highestL = lengthL * 5;
      let resultOfListeningRate = (totalListening * 5) / highestL;
      
      res.json({
        writing: resultOfWritingRate,
        speaking: resultOfSpeakingRate,
        listening: resultOfListeningRate,
        reading: resultOfReadingRate,
      });
    }
    //return res.json(totalRating);
  } catch (error) {
    console.log(error.message);
  }
};

Error, able to solve the async await error but still return me only one response result and after that, it showed cannot sent header错误,能够解决异步等待错误,但仍然只返回一个响应结果,然后显示cannot sent header

在此处输入图像描述 在此处输入图像描述

.forEach() is not async-aware. .forEach()不支持异步。 Use a plain for/of loop instead.请改用普通for/of循环。 In fact, pretty much stop using .forEach() entirely these days as its basically obsolete.事实上,这些天几乎完全停止使用.forEach() ,因为它基本上已经过时了。 With block scope available now with let and const , there is no reason to use .forEach() and it's extra function scope any more.现在使用letconst可以使用块作用域,没有理由使用.forEach()并且它不再是额外的函数作用域。 Use a regular for loop instead.请改用常规for循环。

You can fix this particular code by changing to this:您可以通过更改为以下内容来修复此特定代码:

exports.filterAverageRatingsEachSkillForStudent = async (req, res) => {
    let receiver = req.query.receiver; //array of id ['ABBd23', 'SDSd242', 'dfNJ47']
    try {
        console.log('receiver id', receiver);

        for (let id of reciever) {
            console.log('Query String ', id);
            const findRating = await FeedbackSchema.find({
                receiver: id,
            }).select('ratingL ratingS ratingR ratingW');
        }
    } catch (error) {
        console.log(error.message);
    }
}

It also appears that you must not have disclosed all the code for this function because it looks like you're trying to get findRating , but then you never do anything with it.看起来您一定没有公开此函数的所有代码,因为看起来您正在尝试获取findRating ,但是您从未对它做任何事情。

The error you report about cannot set headers after they are sent does not occur in this code since that error is about sending multiple responses to the same incoming request and you don't send any responses in this code.您报告的错误在发送后无法设置标头在此代码中不会发生,因为该错误是关于向同一个传入请求发送多个响应并且您没有在此代码中发送任何响应。 So, help with that particular error would require disclosing more code or perhaps fixing this function will also fix that (we can't tell since we can't see the code that actually causes that error).因此,解决该特定错误需要披露更多代码,或者修复此功能也可以解决该问题(我们无法确定,因为我们看不到实际导致该错误的代码)。

You can also make use of Promise.all() if there is no dependency between each iteration.如果每次迭代之间没有依赖关系,您也可以使用 Promise.all() 。 Here is the example -这是一个例子 -

exports.filterAverageRatingsEachSkillForStudent = async (req, res) => {
  let receiver = req.query.receiver; //array of id ['ABBd23', 'SDSd242', 'dfNJ47']
  try {
    console.log('receiver id', receiver);
    let results = await Promise.all(receiver.map(async (id) => {
      console.log('Query String ', id);
      return FeedbackSchema.find({
        receiver: id,
      }).select('ratingL ratingS ratingR ratingW'); 
   });
   console.log(results) // this will be an array of results
 } catch (error) {
    console.log(error.message);
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM