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

Node.js接口返回响应时卡在emitHook函数的问题求助

问题:Node.js路由响应卡在emitHook函数,客户端无法收到响应

我用Visual Studio 2022社区版开发小型Node.js应用,遇到两个核心问题:

  • 用户注册路由返回response时,卡在emitHook后端函数,哪怕移除return语句、注释res对象依然如此,调试时添加"skipFiles": [ "<node_internals>/**" ]也未解决。
  • 新建发票路由同样异常:客户端发送fetch请求后收不到响应,Chrome开发者工具显示请求已发送但无法加载响应数据,添加CORS配置也无效。怀疑是Promise相关逻辑导致,求技术帮助。

注册路由代码

registrationRoute.post('/register', async function (req, res) { 
    try {
        await mongoose.connect(uri);
        const { username, password, company } = req.body;
        const existingUser = await User.findOne({ userName : username  });
        if (existingUser) {
            return res.send({ error: "User Name already Taken" });
        }
        const newUser = new User({
            userName : username,
            password: password,
            company: company
        })
        await newUser.save();
        console.log("user successfully registered")
        token = generateToken(newUser.userName)
        return res.status(200).json({token})
    } catch (err) {
        console.error(err)
        return res.status(500).json("unable to register user")
    }
})

emitHook函数代码

function emitHook(symbol, asyncId) {
  active_hooks.call_depth += 1;
  // Use a single try/catch for all hook to avoid setting up one per
  // iteration.
  try {
    // Using var here instead of let because "for (var ...)" is faster than let.
    // Refs: https://github.com/nodejs/node/pull/30380#issuecomment-552948364
    // eslint-disable-next-line no-var
    for (var i = 0; i < active_hooks.array.length; i++) {
      if (typeof active_hooks.array[i][symbol] === 'function') {
        active_hooks.array[i][symbol](asyncId);
      }
    }
  } catch (e) {
    fatalError(e);
  } finally {
    active_hooks.call_depth -= 1;
  }

  // Hooks can only be restored if there have been no recursive hook calls.
  // Also the active hooks do not need to be restored if enable()/disable()
  // weren't called during hook execution, in which case
  // active_hooks.tmp_array will be null.
  if (active_hooks.call_depth === 0 && active_hooks.tmp_array !== null) {
    restoreActiveHooks();
  }
}

新建发票客户端代码

try{
var res = await fetch('/newInvoice',
    {
        method: 'POST',
        headers: {
            'content-type': 'application/json',
        },
        body: JSON.stringify({ message: "sending to server" })
    })
if (res.ok) {
    document.getElementById("invoiceCreatedMessage").innerHTML = "Invoice Successfully created"
}
}catch(err) {
console.log("there was an error: ", err);
}

新建发票路由代码

newInvoiceRoute.post('/newInvoice', function (req, res) {
    res.send({"message": "sending to client"});
})

问题排查与修复建议

  1. 修复数据库重复连接问题
    注册路由中每次请求都调用await mongoose.connect(uri)会重复创建数据库连接,导致连接池阻塞,进而卡住响应流程。应在应用启动时仅连接一次数据库:

    // 入口文件(如app.js)
    const mongoose = require('mongoose');
    const uri = '你的数据库地址';
    
    async function startServer() {
      try {
        await mongoose.connect(uri);
        console.log('数据库连接成功');
        app.listen(3000, () => console.log('服务器启动'));
      } catch (err) {
        console.error('数据库连接失败', err);
      }
    }
    startServer();
    

    随后删除注册路由中的await mongoose.connect(uri);语句。

  2. 排查异步钩子阻塞
    emitHook是Node.js内部异步钩子函数,卡住说明项目中存在使用async_hooks的第三方库或自定义代码,存在阻塞或死循环。暂时禁用这类代码,测试是否恢复正常。

  3. 优化调试配置
    确保VSCode的.vscode/launch.json配置正确,重启调试会话生效:

    {
      "version": "0.2.0",
      "configurations": [
        {
          "type": "node",
          "request": "launch",
          "name": "Launch Program",
          "skipFiles": [
            "<node_internals>/**"
          ],
          "program": "${workspaceFolder}/app.js"
        }
      ]
    }
    
  4. 完善客户端请求逻辑
    客户端fetch若未读取响应体,会导致服务端认为请求未完成,进而卡住连接。补充响应体读取逻辑:

    try {
      const res = await fetch('/newInvoice', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ message: "sending to server" })
      });
      if (res.ok) {
        const data = await res.json(); // 必须读取响应体
        document.getElementById("invoiceCreatedMessage").innerHTML = "Invoice Successfully created";
      }
    } catch(err) {
      console.log("there was an error: ", err);
    }
    

    同时确保服务端全局启用CORS:

    const cors = require('cors');
    app.use(cors());
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:55:59