繁体   English   中英

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

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

我有两个模式,用户和产品。 用户架构是我存储所有产品 ID 和用户添加到购物车的商品数量的地方。

在此处输入图片说明

当用户向“/checkout”发出请求时,它应该更新数量,然后将其从购物车中删除。 当我结帐数量未更新数量时遇到问题。

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.products.map(...)函数上,因为您永远不会等待您在地图中创建的所有承诺都得到解决。

换句话说, map函数返回一个待处理的 promise 数组,但它不会等待它们完成,因此执行会继续执行到res.status(...) map代码已被执行。

您有不同的选择来解决它,但主要是您需要处理map函数返回的承诺数组,并在结束代码之前等待它们完成。 Google Developers Web 基础指南 中对如何使用async/await处理这种情况有一个很好的解释。

我通常利用Promise.all()函数,它从承诺数组中返回一个承诺,因此您可以等到map的代码对数组中的每个项目(即您的情况下的product并行执行。 您可以在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

// ...

一个好的做法是在Promise.all()周围使用try {} catch(err) {}块来处理某些 promise 被拒绝的情况。

暂无
暂无

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

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