新增Itinerary时递增Location的clicks字段报错及功能实现
问题分析与修复方案
报错原因
你碰到的ERR_HTTP_HEADERS_SENT错误,根源是保存Itinerary后立刻调用了res.send(data),已经把响应发给客户端了,但后续Location的更新操作里又尝试调用res.send(data2)或res.status(500)——HTTP协议要求每个请求只能发送一次响应,重复发送就会触发这个错误。
另外原代码的Location.findByIdAndUpdate用法有误:locationsId是数组,findByIdAndUpdate只能更新单个文档,没法批量处理数组里的所有Location ID。
修复后的代码
exports.create = (req, res) => { // 验证请求 if (!req.body.name || !req.body.dateStart || !req.body.dateEnd) { res.status(400).send({ message: "内容不能为空!" }); return; } // 创建Itinerary实例 const itinerary = new Itinerary({ name: req.body.name, dateStart: req.body.dateStart, dateEnd: req.body.dateEnd, userEmail: req.body.userEmail, locationsId: req.body.locationsId, cityId: req.body.cityId, userId: req.body.userId, usersId: req.body.usersId }); // 保存Itinerary并批量更新Location的clicks itinerary.save() .then(savedItinerary => { // 如果locationsId数组为空,直接返回结果 if (!savedItinerary.locationsId || savedItinerary.locationsId.length === 0) { return res.send(savedItinerary); } // 批量更新所有匹配的Location文档,clicks递增1 return Location.updateMany( { _id: { $in: savedItinerary.locationsId } }, { $inc: { clicks: 1 } } ) .then(updateResult => { // 返回Itinerary信息和更新结果 res.send({ itinerary: savedItinerary, locationUpdate: { matchedCount: updateResult.matchedCount, modifiedCount: updateResult.modifiedCount } }); }); }) .catch(err => { res.status(500).send({ message: err.message || "创建Itinerary或更新Location时发生错误。" }); }); };
关键修改点
- 移除提前发送响应:把
res.send放在所有异步操作完成后,确保只发送一次响应。 - 批量更新Location:用
updateMany替代findByIdAndUpdate,通过{ _id: { $in: savedItinerary.locationsId } }匹配数组中所有的Location ID,实现批量递增clicks。 - 空数组处理:增加对
locationsId为空数组的判断,避免不必要的数据库操作。 - 统一错误处理:所有异步操作的错误都通过最外层的
catch捕获,返回统一的错误响应。
内容的提问来源于stack exchange,提问作者prettyMaria
相关产品推荐
相关产品推荐

