简体   繁体   English

如何使用 mongoose 更新 MongoDB 中的数组?

[英]How to update an array in MongoDB using mongoose?

I have two schemas, User, and Product.我有两个模式,用户和产品。 The User schema is where I store all the product ID and the number of items that the user added to the cart.用户架构是我存储所有产品 ID 和用户添加到购物车的商品数量的地方。

在此处输入图片说明

When the user makes a request to '/checkout' it should update the quantity and then remove it from the cart.当用户向“/checkout”发出请求时,它应该更新数量,然后将其从购物车中删除。 I am having an issue when I checkout the quantity is not updating the quantity.当我结帐数量未更新数量时遇到问题。

router.post('/checkout', auth, catchAsync(async (req, res) => {
    const user = await User.findById(req.session.userId);
    const err = [];
    if (user && user.products.length > 0) {

        user.products.map(async (product) => {
            let total = 0;
            const p = await Product.findById(product.productID);

            if (p.quantity > 0 && p.quantity > product.quantity) {
                console.log('IN');
                total = p.quantity - product.quantity;
                console.log(total);

                await Product.findOneAndUpdate({ _id: product.productID }, { $set: { quantity: total } });
            } else {
                err.push(`Item, ${p.name} is sold out`);
            }
        });
        await User.findOneAndUpdate({ _id: req.session.userId }, { $set: { products: [] } });
        if (err.length) {
            return res.status(500).json({ message: err });
        }
        return res.status(200).json({ message: 'OK' });
    }
    return res.status(200).json({ message: 'Empty cart' });
}));

User Schema:用户架构:

在此处输入图片说明

Product Schema:产品架构:

产品

I believe the problem in your code is at the user.products.map(...) function, because you never wait for all the promises you create in the map to resolve.我相信您的代码中的问题出在user.products.map(...)函数上,因为您永远不会等待您在地图中创建的所有承诺都得到解决。

In other words, the map function returns an array of pending promises, but it will not wait for them to be done, and therefore the execution continues through the rest of the code reaching the res.status(...) before any of the code in map had been executed.换句话说, map函数返回一个待处理的 promise 数组,但它不会等待它们完成,因此执行会继续执行到res.status(...) map代码已被执行。

You have different options to solve it, but mainly you need to take care of the array of promises returned by the map function and wait for their completion, before you end your code.您有不同的选择来解决它,但主要是您需要处理map函数返回的承诺数组,并在结束代码之前等待它们完成。 There is a very good explanation of how to handle this situation with async/await at Google Developers Web fundamentals guide .Google Developers Web 基础指南 中对如何使用async/await处理这种情况有一个很好的解释。

I usually leverage Promise.all() function, which returns a single promise from the array of promises, and therefore you can wait until the code in map is executed in parallel for each item in the array (ie product in your case).我通常利用Promise.all()函数,它从承诺数组中返回一个承诺,因此您可以等到map的代码对数组中的每个项目(即您的情况下的product并行执行。 You can read more about it at MDN documentation .您可以在MDN 文档 中阅读有关它的更多信息。

// ...

let promisesArray = user.products.map(async product => {...});
// promisesArray should look like: [Promise { <pending> }, Promise { <pending> }, … ]

// Using Promise.all we wait for each of them to be done in parallel
await Promise.all(promisesArray);

// Now you are certain the code in the map has been executed for each product

// ...

A good practice as well is to use try {} catch(err) {} block around the Promise.all() to handle cases of some promise being rejected.一个好的做法是在Promise.all()周围使用try {} catch(err) {}块来处理某些 promise 被拒绝的情况。

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

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