Node.js Mongoose在forEach()中保存同一文档

Node.js Mongoose在forEach()中保存同一文档,node.js,mongodb,asynchronous,mongoose,async-await,Node.js,Mongodb,Asynchronous,Mongoose,Async Await,我正在尝试创建一个网站,为我个人感兴趣的球队展示一些即将到来的足球比赛 我使用forEach()循环遍历团队ID列表,并为每个团队调用api以获取即将到来的比赛数据,并使用mongoose save()将其保存到mongodb集合中 我遇到了一个错误,同一文档被多次保存并以随机顺序保存,尽管我编写了代码来解决这个问题。我认为我在学习node.js的过程中可能会犯一些关于异步的基本错误 非常感谢您的帮助 var request = require("request"); con

我正在尝试创建一个网站,为我个人感兴趣的球队展示一些即将到来的足球比赛

我使用forEach()循环遍历团队ID列表,并为每个团队调用api以获取即将到来的比赛数据,并使用mongoose save()将其保存到mongodb集合中

我遇到了一个错误,同一文档被多次保存并以随机顺序保存,尽管我编写了代码来解决这个问题。我认为我在学习node.js的过程中可能会犯一些关于异步的基本错误

非常感谢您的帮助

var request = require("request");
const Match = require("../models/matchSchema");
const moment = require("moment-timezone");

const team_id = [
  "40", //liv
  "33", //utd
  "47", //tot
  "49", //chel
  "541", //Real
];

const newMatches = () => {
  team_id.forEach((element) => {
    const options = {
      method: "GET",
      url: "https://v3.football.api-sports.io/fixtures",
      qs: {
        team: element,
        next: "1",
      },
      headers: {
        "x-rapidapi-host": "v3.football.api-sports.io",
        "x-rapidapi-key": <myAPIkey>,
        "Content-Type": "application/json",
      },
    };
    request(options, async (error, response, body) => {
      data = JSON.parse(body);
      if (error) throw new Error(error);

      const newMatch = await Match.findOne({
        outcomeID: data.response[0].fixture.id,
      });

      //to ensure the match doesnt exist

      if (!newMatch) {
        const newMatchCreate = await Match.create({
          outcomeID: data.response[0].fixture.id,
          category: "soccer",
          team1: data.response[0].teams.home.name,
          team2: data.response[0].teams.away.name,
          timeStart: moment
            .utc(data.response[0].fixture.date)
            .format("MM-DD HH:mm"),
        });
        await newMatchCreate.save();
      }
    });
  });
};

module.exports = newMatches;
var请求=要求(“请求”);
const Match=require(“../models/matchSchema”);
常数时刻=要求(“时刻时区”);
施工队id=[
“40”//liv
“33”//utd
“47”//tot
“49”//chel
“541”//Real
];
常量newMatches=()=>{
团队id.forEach((元素)=>{
常量选项={
方法:“获取”,
url:“https://v3.football.api-sports.io/fixtures",
qs:{
团队:元素,
下一个:“1”,
},
标题:{
“x-rapidapi-host”:“v3.football.api sports.io”,
“x-rapidapi-key”:,
“内容类型”:“应用程序/json”,
},
};
请求(选项,异步(错误,响应,正文)=>{
data=JSON.parse(body);
如果(错误)抛出新错误(错误);
const newMatch=wait Match.findOne({
outcomeID:data.response[0].fixture.id,
});
//以确保匹配不存在
如果(!newMatch){
const newMatchCreate=等待Match.create({
outcomeID:data.response[0].fixture.id,
类别:"足球",,
team1:data.response[0]。teams.home.name,
team2:data.response[0]。teams.away.name,
时间起点:时刻
.utc(数据.response[0].fixture.date)
.格式(“MM-DD HH:MM”),
});
等待newMatchCreate.save();
}
});
});
};
module.exports=newMatches;

您似乎已将
wait
放入调用中,以使调用同步到新对象上的
Match.create()
save()
,我猜新对象会写入文件。但是您忽略了
request()
调用是异步的,并且只在服务器响应其请求时运行其回调函数。因此,整个循环可能在运行请求的第一个回调之前完成。然后文件会以任何顺序保存

我不能确切地告诉你发生了什么,你期望什么,所以我不确定应该写什么文件,什么时候写,但要确保你假设的数据如预期的那样存在,只要它一进来就记录下来,或者在你迭代之前记录下来