![](/img/trans.png)
[英]How to update multiple objects in array in a single mongodb document using mongoose
[英]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.