为了账号安全,请及时绑定邮箱和手机立即绑定

Mongoose Async 查找所有并更新每个

Mongoose Async 查找所有并更新每个

九州编程 2021-06-21 21:03:49
我的小费游戏很少。游戏完成后,我从猫鼬数据库中获取所有提示,然后使用 forEach 迭代这些提示。对于这些提示中的每一个,我都会获取用户名并从 mongoose db 加载用户以增加该用户的积分,然后将用户更改保存回 db。一个用户可以拥有多个提示。Tips.find({...}).exec(function(err, gameTips) {   gameTips.forEach(tip, i) => {      User.findOne({         username: tip.username      }).exec(function(err, user) {          user.points = user.points + 1;          user.save(function(err) {             console.log("Points were increased");          });      });   });}现在我的问题是用户的 findOne 是在保存上一个提示处理之前完成的。所以积分不会正确增加。用户:testUser 有 4 个提示 | 预期:testUser.points = 4; | 当前:testUser.points = 2;是否有可能异步执行此操作,以便为所有用户查找和保存将一个接一个地完成,以便每次我这样做:user.points = user.points +1;我会在增加之前有更新的积分吗?
查看完整描述

2 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

发生的情况是您使用前面的点来计算下一个分数,而不是使用 mongoDB$inc运算符


选项 1 使用回调,丑陋且根本不可读


Tips.find({})

  .exec(function(err, gameTips) {

    if(err) {

      console.error(err);

      return;

    }

    gameTips.forEach(tip => {

      User.findOneAndUpdate(

        { username: tip.username },

        { $inc: { points: tip.points }}

      ).exec(function(err, user) {

        if(err) {

          console.error(err);

          return;

        }

        console.log("Points were increased");

      })

    })

  })

选项 2 使用Promises,更具可读性Promise.all()


Tips.find({})

  .then(gameTips => Promise.all(gameTips.map(tip => User.updateOne(

    { username: tip.username},

    { $inc: { points: tip.points } }

  )))

  .then(() => {

    console.log("Points were increased");

  })

  .catch(console.error)

选项 3 使用async/await,我最喜欢的,简单易读


async function run() {

  try {

    const gameTips = await Tips.find({});

    await Promise.all(gameTips.map(tip => User.updateOne(

      { username: tip.username},

      { $inc: { points: tip.points } }

    )));

    console.log("Points were increased");

  } catch (err) {

    console.error(err);

  }

}


查看完整回答
反对 回复 2021-06-24
?
开满天机

TA贡献1786条经验 获得超13个赞

您不能像在 中使用异步代码那样使用它forEach,它不会产生所需的结果。您可以使用for ofwithasync await来获得更清晰的代码:


 async function updateTips() {

 try {

    const tips = await Tips.find({condition: 'condition'})

    if (tips.length) { // check for empty result

        for (const tip of tips) {

            let user = await User.findOne({ username: tip.username })

            if (user) {

                user.points = user.points + 1

                await user.save()

                console.log('Points were increased')

            }

        }

    }

 } catch (err) {

     // handle errors here

 }

}


updateTips()


查看完整回答
反对 回复 2021-06-24
  • 2 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信