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

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 };

排查步骤

  1. 检查前端请求逻辑:确认按钮点击、请求发送的代码只执行一次。
  2. 检查后端路由配置:确保CreateRoom只被挂载到目标路由一次。
  3. 关闭热重载工具测试:如果使用nodemon等工具,先手动重启服务器,看日志是否还重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 17:15:15