如何验证指定Purchase是否已存在关联Dispute?(Socket.io场景)
问题
我正在使用Socket.io进行开发,当前Purchase模型未设置disputes字段,但Dispute模型关联了Purchase字段。请问如何验证某条Purchase是否已经存在对应的Dispute?以下是我的相关代码实现:
socket.on( "new cause", async (purchase, userId, msgCause, sellerId, callback, res) => { if (!msgCause || msgCause === "") { return callback({ error: true }); } const disputeExist = await Dispute.findOne({ purchaseId: purchase }).populate({ path: 'purchaseId' }).lean(); var erros = []; if ( purchase == disputeExist.purchaseId ) { erros.push({ text: "Dispute already exist" }); } if (erros.length > 0) { res.render("user/chat", { erros }); } else { const dispute = await new Dispute({ buyer: userId, seller: sellerId, purchaseId: purchase, message: msgCause, }).save(); if (!dispute) { return callback({ error: true, message: "dispute save error" }); } const user = await User.findOneAndUpdate( { _id: userId }, { $push: { disputes: dispute._id } } ).lean(); if (!user) { return callback({ error: true, message: "user save error" }); } //io.to(purchase).emit("chat message", new Date().toLocaleString("en-us") + msgCause); callback({ error: false }); } } );
解决方案
你的代码存在两个核心问题,导致无法正确验证Purchase是否已有对应Dispute:
- 当没有找到对应Dispute时,
disputeExist会是null,此时访问disputeExist.purchaseId会直接抛出错误 - 不需要用
populate拉取关联的Purchase数据,只需验证是否存在关联记录即可
修改后的验证逻辑如下:
socket.on( "new cause", async (purchase, userId, msgCause, sellerId, callback, res) => { if (!msgCause || msgCause === "") { return callback({ error: true }); } // 直接查询是否存在关联该purchase的Dispute,无需populate const disputeExist = await Dispute.exists({ purchaseId: purchase }); const errors = []; if (disputeExist) { errors.push({ text: "该订单已存在纠纷记录" }); } if (errors.length > 0) { // Socket.io场景下建议通过callback返回错误,而非res.render(后者为HTTP请求处理方式) return callback({ error: true, errors }); } try { const dispute = await Dispute.create({ buyer: userId, seller: sellerId, purchaseId: purchase, message: msgCause, }); await User.findOneAndUpdate( { _id: userId }, { $push: { disputes: dispute._id } } ); // io.to(purchase).emit("chat message", `${new Date().toLocaleString("en-us")} ${msgCause}`); callback({ error: false }); } catch (err) { callback({ error: true, message: err.message }); } } );
关键修改点说明:
- 使用
Dispute.exists({ purchaseId: purchase })替代findOne,直接返回布尔值,更高效且避免空值报错 - 修正变量名拼写错误(
erros改为errors) - 用
try/catch包裹数据库操作,统一捕获保存过程中的异常 - 调整错误返回逻辑,适配Socket.io的回调机制
内容的提问来源于stack exchange,提问作者XR Sistemas
相关产品推荐
相关产品推荐

