You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB数据存入集合正常,但res()返回数据滞后一步的问题排查

问题:购物车接口返回数据滞后一步

所有功能运行正常,但接口返回的数据总是滞后一步,多次重写代码仍无法定位问题。以下是基于Express.js、Node.js和MongoDB开发的后端代码:

export const addToCart = async (req, res) => { 
  try {
    const cart = await CartModul.findOne({ user: req.userId });
    if (cart) {
      const product_id = req.body.product_id;
      const item = cart.cartItems.find((c) => c.product_id == product_id);
      console.log("item", item);
      if (item) {
        try {
          const cart = await CartModul.findOneAndUpdate(
            { user: req.userId, "cartItems.product_id": product_id },
            {
              "cartItems.$": {
                ...req.body,
                quantity: item.quantity + req.body.quantity,
                totalPrice: item.totalPrice + req.body.price,
              },
            }
          );
          if (cart) {
            return res.status(200).json({ cart });
          }
        } catch (error) {
          return res.status(400).json({ error });
        }
      } else {
        try {
          const cart = await CartModul.findOneAndUpdate(
            { user: req.userId },
            {
              $push: {
                cartItems: req.body,
              },
            }
          );
          if (cart) {
            return res.status(200).json({ cart });
          }
        } catch (error) {
          return res.status(400).json({ error });
        }
      }
    } else {
      try {
        const cart = new CartModul({
          user: req.userId,
          cartItems: req.body,
        });
        cart.save();
        res.json(cart);
      } catch (error) {
        return res.status(400).json({ error });
      }
    } 
  } catch (error) {
    return res.status(400).json({ error })
  }
};

问题原因

  1. findOneAndUpdate()默认返回更新前的文档:MongoDB的这个方法默认行为是返回更新操作执行前的旧数据,所以你拿到的cart是修改前的版本,导致返回数据滞后一步。
  2. cart.save()未使用await:创建新购物车时,调用cart.save()没有加await,可能在文档还没保存到数据库时就返回了,导致返回的数据不是最终持久化的版本。

修复方案

1. 给findOneAndUpdate()添加{ new: true }选项

这个选项会让方法返回更新后的最新文档,而不是旧数据。

2. 给cart.save()加上await

确保文档成功保存到数据库后再返回响应。

3. 简化嵌套try-catch

不需要在每个分支单独写try-catch,外层的try-catch已经可以处理所有错误,代码更简洁。

修复后的完整代码

export const addToCart = async (req, res) => { 
  try {
    const cart = await CartModul.findOne({ user: req.userId });
    if (cart) {
      const product_id = req.body.product_id;
      const item = cart.cartItems.find((c) => c.product_id == product_id);
      console.log("item", item);
      
      let updatedCart;
      if (item) {
        updatedCart = await CartModul.findOneAndUpdate(
          { user: req.userId, "cartItems.product_id": product_id },
          {
            "cartItems.$": {
              ...req.body,
              quantity: item.quantity + req.body.quantity,
              totalPrice: item.totalPrice + req.body.price,
            },
          },
          { new: true } // 返回更新后的文档
        );
      } else {
        updatedCart = await CartModul.findOneAndUpdate(
          { user: req.userId },
          { $push: { cartItems: req.body } },
          { new: true } // 返回更新后的文档
        );
      }
      
      return res.status(200).json({ cart: updatedCart });
    } else {
      const cart = new CartModul({
        user: req.userId,
        cartItems: req.body,
      });
      await cart.save(); // 等待保存完成
      return res.json(cart);
    } 
  } catch (error) {
    return res.status(400).json({ error });
  }
};

内容的提问来源于stack exchange,提问作者Adlan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:45:18