亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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 關注
  • 193 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號