提问人:Ope Afolabi 提问时间:12/27/2021 更新时间:12/27/2021 访问量:268
返回值延迟 - nodejs & mongoose
Delay in return value - nodejs & mongoose
问:
我对 nodejs 相当陌生,我正在做一个来自 devchallenges.io (Shoppingify) 的全栈开发人员挑战。下面,我尝试根据用户单击以增加或减少项目数量来增加数量值。但是,请求的返回值与数据库中的实际值之间存在轻微的延迟。似乎该值会立即更新,这很好,但是,请求中的返回值是以前的值,而不是数据库中的当前数量值。
mongoDB 数据库
// @route PUT api/list/item/quantity/:id
// @desc update item quantity
// @access Private
router.put('/item/quantity/:id', auth, async (req, res) => {
const { action } = req.body;
try {
let list = await List.findOne({ user: req.user.id });
// find current quantity
const item = list.items.find((item) => {
return item._id.toString() === req.params.id;
});
// increase quantity
if (action === 'increase') {
list = await List.findOneAndUpdate(
{ 'items._id': req.params.id },
{ $set: { 'items.$.quantity': item.quantity + 1 } },
{ new: true }
);
} else {
// decrease quantity
list = await List.findOneAndUpdate(
{ 'items._id': req.params.id },
{ $set: { 'items.$.quantity': item.quantity - 1 } },
{ new: true }
);
}
res.json(item.quantity);
} catch (error) {
console.error(error.message);
res.status(500).send('Server Error');
}
});
答:
1赞
Tom Slabbaert
12/27/2021
#1
你在这里定义:item
const item = list.items.find((item) => {
return item._id.toString() === req.params.id;
});
此时是对象的“旧”版本,您希望在更新对象时执行相同的操作,然后才返回它。list
list
// this is the original "list" item
let item = list.items.find((item) => {
return item._id.toString() === req.params.id;
});
...
update list
...
// now "list" is updated
item = list.items.find((item) => {
return item._id.toString() === req.params.id;
});
我只添加两个额外的技巧来提高性能,它们是相互排斥的,因此您必须选择两者之一。
- 在更新查询中添加,如果我猜测该集合在字段上没有索引(如果有,这通常是一个坏主意)。这意味着当您仅使用字段进行更新时,Mongo 需要更长的时间才能找到对象。这是对两个更新的快速更改:
list._id
items
item._id
list = await List.findOneAndUpdate(
{ _id: list._id, 'items._id': req.params.id },
{ $set: { 'items.$.quantity': item.quantity - 1 } },
{ new: true }
);
- (我的首选选项)使用update arrayFilters选项在单个调用中执行此操作,如下所示:
const list = await List.findOneAndUpdate(
{
user: req.user.id,
},
{
$inc: {
'items.$[elem].quantity': action === 'increase' ? 1 : -1,
},
},
{
arrayFilters: [
{
'elem._id': new ObjectId(req.params.id),
},
],
new: true,
});
const item = list.items.find((item) => {
return item._id.toString() === req.params.id;
});
在我看来,现在您的路由看起来好多了,您也从 2 db 调用减少到 1。
评论
0赞
Ope Afolabi
12/28/2021
你是明星,谢谢你:)
评论