【问题标题】:Mongoose document created. But change is not reflected immediately in the collection已创建 Mongoose 文档。但是变化不会立即反映在集合中
【发布时间】:2020-11-13 14:38:33
【问题描述】:
favoriteRouter
    .route('/:dishId')
    .post(cors.corsWithOptions, authenticate.verifyUser, (req, res, next) => {
        Favorites.findOne({ user: req.user._id })
            .then(
                (favoriteList) => {
          //***SECTION A START//***
                    if (favoriteList == null) {
                        Favorites.create({
                            user: req.user._id,
                        })
                            .then(
                                (favoriteList) => {
                                    console.log('promise resolved');
                                },
                                (err) => {
                                    console.log('promise error');
                                    next(err);
                                }
                            )
                            .catch((err) => next(err));
                    }
          //***SECTION A END//***
                    Favorites.findOne({ user: req.user._id })
                        .then((favoriteList) => {
          //***SECTION B START//***
                            if (favoriteList != null) {
                                favoriteList.dishes.push(req.params.dishId);
                                favoriteList
                                    .save()
                                    .then(
                                        (favoriteList_c) => {
                                            res.statusCode = 200;
                                            res.setHeader('Content-Type', 'application/json');
                                            res.json(favoriteList_c);
                                        },
                                        (err) => {
                                            next(err);
                                        }
                                    )
                                    .catch((err) => {
                                        next(err);
                                    });
                            } else {
                                err = new Error(
                                    'Something wrong with favorite list document of user ' +
                                        req.user._id
                                );
                                err.status = 404;
                                return next(err);
                            }
          //***SECTION B END//***
                        })
                        .catch((err) => next(err));
                },
                (err) => next(err)
            )
            .catch((err) => next(err));
    });

如果用户在 /:dishId 上发帖,但该用户没有最喜欢的文档,则创建一个新文档 在第 A 部分(用代码标记)。该文档在打印承诺已解决时创建得很好。但是在 SECTION B 中执行 else 部分,这意味着没有找到新创建的文档。但是,如果用户再次尝试,则意味着在下一步中它可以找到该文档并在 SECTION B IF 块中更新。有什么我想念的吗。我是nodejs的初学者,请帮忙!

【问题讨论】:

  • A 部分中的文档是否被插入到数据库中?你检查了吗?
  • 我没有检查。但我认为它会被插入,如果不是,那么它在下一次通话中的工作方式。
  • 在 A 部分,将 Favorites.create 替换为 Favorites.insertOne 并检查
  • 我认为猫鼬模型没有 insertOne 功能。

标签: node.js mongodb mongoose


【解决方案1】:

您必须首先了解 NodeJs 异步代码的工作方式。 NodeJs 的默认行为是,每当它发现一个 I/O 操作时,它会根据操作系统处理它的能力将该操作委托给操作系统或工作线程,并移至下一行代码。

根据您的代码,第一个 Favorite.findOne() 被调用,当它被引擎执行时,控制跳转到下一行代码,即第二个 Favorite.findOne() 并尝试找到文件。但是此时文档还没有创建,所以这就是你第一次运行时没有找到记录的原因,但是第二次使用Favorite.create()创建了文档里面的第一个findOne's then()

因此,您需要通过将第二个 findOne() 放入 firstOne 来重构您的代码。好吧,你知道吗,你不需要写两次 Favorite.findOne()。一个 findOne() 就足以满足您的要求。

Mongoose 利用了 Promise,这意味着我们可以在控制器方法中使用 async/await。


favoriteRouter
  .route('/:dishId')
  .post(cors.corsWithOptions, authenticate.verifyUser, async  (req, res) => {
    try {
      // find the FavoriteList
      let favoriteList = await Favorites.find({
        user: req.user._id
      });
      // using a library called lodash for simplicity
      // you have to install it using npm i lodash and
      // require at the top using let _ = require('lodash')
      
      //If not found, create one and assign it to favorite list
      if (_.isEmpty(favoriteList)) {
        favoriteList = await Favorites.create({
          user: req.user._id
        });
      }
      
    // at this point, you must have a favoriteList either a found one or brand new
      favoriteList.dishes.push(req.params.dishId)
      let favoriteList_c = await favoriteList.save();
      return res.json(favoriteList_c)
    } catch (err) {
      //handle error
      res.status(501).send({message: 'unable to perform operation'});
    }
  });

我在这里添加了异步到控制器回调函数并删除了下一个参数,因为我们不需要它。如需参考,请访问this

注意:如果您只是将我编写的代码复制/粘贴到您的程序中,它可能无法正常工作,但该方法相当简单,您可能需要根据 Mongoose API 文档进行一些调整,尤其是 save() 和创建()。 我相信他们会在创建对象后返回它。

祝你好运!!

【讨论】:

    【解决方案2】:

    您的代码没有问题,但是当 A 部分的 findOne 被同时执行时 B 部分的代码被执行。 使用 promise.then 创建一个复杂的代码。请改用 async/await。

    以下只是您代码中使用 async/await 的一个小 sn-p

    let favoriteList = await Favorites.findOne({ user: req.user._id });
    
    if (favoriteList == null) {
        await Favorites.create({
            user: req.user._id,
        })
    }
    favoriteList = await Favorites.findOne({ user: req.user._id })
    if (favoriteList != null) {
        favoriteList.dishes.push(req.params.dishId);
        await favoriteList.save();
    
        res.statusCode = 200;
        res.setHeader('Content-Type', 'application/json');
        res.json(favoriteList_c);
    
    } else {
        err = new Error(
            'Something wrong with favorite list document of user ' +
            req.user._id
        );
    }
    

    【讨论】:

      猜你喜欢
      • 2020-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 2021-10-01
      • 1970-01-01
      • 2012-10-06
      相关资源
      最近更新 更多