Mongoose批量实现数据存在更新不存在创建,修复响应头重复发送报错
错误原因
- 变量泄漏:循环使用
var声明变量,var没有块级作用域,等数据库异步操作回调触发时,循环已经执行完毕,拿到的item永远是列表的最后一个元素,会导致逻辑执行错误 - 重复发送响应:你在循环的每个数据库操作回调中都调用了
res.send,HTTP响应只能返回一次,第一个操作完成触发res.send后,后续操作再调用就会抛出你遇到的ERR_HTTP_HEADERS_SENT错误 - 逻辑冗余:先查询再判断更新/新增的逻辑可以直接用MongoDB内置的upsert能力替代,既减少一次数据库查询,还能避免并发读写的竞争问题
修复方案
你不需要手动判断数据是否存在,直接调用updateOne开启upsert参数即可自动完成「存在则更新、不存在则新建」的逻辑,配合async/await+Promise.all批量处理所有条目,所有操作完成后统一返回结果即可:
app.put("/update_personal", async (req, res) => { try { const { personalName: personalNameList, userId } = req.body // 生成所有条目的操作Promise const operationPromises = personalNameList.map(personalName => { return Personal.updateOne( { personalName }, { $push: { listUserId: userId } }, { upsert: true, // 开启不存在则新建的能力 new: true, strict: false } ) }) // 等待所有操作执行完成 const results = await Promise.all(operationPromises) // 统一返回响应 res.json({ code: 200, msg: "操作完成", data: results }) } catch (err) { // 统一捕获所有错误返回 res.status(500).json({ code: 500, msg: "操作失败", error: err.message }) } })
以上代码完全符合你的需求,还解决了原代码的性能问题和并发风险。
内容的提问来源于stack exchange,提问作者Lộc Trần Phước
相关产品推荐
相关产品推荐

