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"}); })
问题排查与修复建议
修复数据库重复连接问题
注册路由中每次请求都调用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);语句。排查异步钩子阻塞
emitHook是Node.js内部异步钩子函数,卡住说明项目中存在使用async_hooks的第三方库或自定义代码,存在阻塞或死循环。暂时禁用这类代码,测试是否恢复正常。优化调试配置
确保VSCode的.vscode/launch.json配置正确,重启调试会话生效:{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Launch Program", "skipFiles": [ "<node_internals>/**" ], "program": "${workspaceFolder}/app.js" } ] }完善客户端请求逻辑
客户端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
相关产品推荐
相关产品推荐

