Node.js中CreateRoom函数重复执行问题咨询
Node.js MongoDB CreateRoom函数日志重复输出问题
我正在学习Node.js,编写了一段操作MongoDB的CreateRoom函数,预期功能是当聊天室名称不存在时创建对应的文档。但运行后发现函数内的日志重复输出,如____x出现两次,其他日志也存在重复情况,完全无法理解该现象,恳请解惑。
代码示例
const mongoose = require('mongoose'); const Chat = require("../Models/Chat"); async function CreateRoom(req, res) { const { room, username, _id } = req.body; console.log(`CHAT: createRoom ${room}`); const chat = await Chat.findOne({ "room": room }).exec(); console.log(`____x`) if (chat) { console.log(`____0`) res.sendStatus(409); // Conflict } console.log(`____1`) const result = await Chat.create({ room: room, message: [ { text: "Room created", from: _id, } ] }); console.log("____2") if (!result) { console.log(`CHAT: createRoom ${room} failed`); res.sendStatus(400); } console.log("____3") console.log(`CHAT room created: ${room}`); return res.sendStatus(201); } module.exports = { CreateRoom };
运行输出
CHAT: createRoom lobby ____x ____1 ____x ____1 ____2 ____3 CHAT room created: lobby ____2 ____3 CHAT room created: lobby
问题分析与解决
核心原因:函数被触发了两次
从日志完整执行两遍的规律来看,最直接的原因是CreateRoom函数被调用了两次,常见触发场景包括:
- 前端重复发送请求:比如按钮绑定了两次点击事件、请求被意外调用两次,或者浏览器自动重试请求。
- 后端路由重复挂载:比如同一个
POST路由被定义了两次,或者热重载工具(如nodemon)重启服务器时未清理旧路由导致重复注册。 - 中间件异常:某些中间件逻辑导致请求被转发或重复处理。
代码本身的隐患(需修复)
即使解决了重复调用问题,代码还存在严重bug:当chat已存在时,调用res.sendStatus(409)后未终止函数执行,后续代码会继续运行,最终引发Cannot set headers after they are sent to the client错误。
修复后的代码
const mongoose = require('mongoose'); const Chat = require("../Models/Chat"); async function CreateRoom(req, res) { const { room, username, _id } = req.body; console.log(`CHAT: createRoom ${room}`); const chat = await Chat.findOne({ "room": room }).exec(); console.log(`____x`) if (chat) { console.log(`____0`) res.sendStatus(409); // Conflict return; // 终止函数,避免后续代码执行 } console.log(`____1`) const result = await Chat.create({ room: room, message: [ { text: "Room created", from: _id, } ] }); console.log("____2") if (!result) { console.log(`CHAT: createRoom ${room} failed`); res.sendStatus(400); return; // 终止函数 } console.log("____3") console.log(`CHAT room created: ${room}`); return res.sendStatus(201); } module.exports = { CreateRoom };
排查步骤
- 检查前端请求逻辑:确认按钮点击、请求发送的代码只执行一次。
- 检查后端路由配置:确保
CreateRoom只被挂载到目标路由一次。 - 关闭热重载工具测试:如果使用nodemon等工具,先手动重启服务器,看日志是否还重复。
内容的提问来源于stack exchange,提问作者MikeB
相关产品推荐
相关产品推荐

