为什么Mongoose仅在执行独立Node.js脚本时断开连接且进程不退出
问题核心原因解答
1. 独立脚本运行时Mongoose处于断开状态的原因
运行node test.js会启动独立的Node.js进程,和运行server.js的Express服务进程内存完全隔离,没有任何状态共享:
- server.js中初始化的Mongoose连接仅存在于server.js的进程上下文,test.js执行时不会自动加载运行server.js的代码,没有做过Mongoose连接初始化,因此默认readyState为0(未连接)。该状态和server.js中的disconnected事件无关,两个进程的连接状态完全独立。
- 路由逻辑运行在server.js进程中,已经完成了Mongoose连接初始化,因此操作Schema正常。
2. 加连接逻辑后进程无法自动退出的原因
Mongoose默认维持数据库长连接,会持有Node.js事件循环的活跃句柄,只要连接未主动关闭,Node进程检测到事件循环存在活跃任务就不会自动终止。
修复方案
你当前在test.js中主动判断连接状态并初始化连接的写法没有负面影响,是独立脚本访问MongoDB的标准实现,仅需在数据库操作完成后主动关闭Mongoose连接即可让进程正常退出,修改后的test.js代码如下:
const RefreshToken = require('./models/refreshtoken.js'); const mongoose = require('mongoose'); (async () => { await testGetToken(); console.log("ran testGetToken()"); // 所有操作完成后主动关闭数据库连接,释放事件循环句柄 await mongoose.disconnect(); })().catch(async e => { console.error(e) // 异常场景也需关闭连接,避免进程挂起 await mongoose.disconnect(); process.exit(1); }); async function testGetToken() { try { console.log("here in testGetToken() call") console.log("pre if mongoose.connection = " + mongoose.connection.readyState); if (mongoose.connection.readyState != 1) { await mongoose.connect(process.env.MONGODB_URI, {useNewUrlParser: true, useUnifiedTopology: true}) } console.log("post if mongoose.connection = " + mongoose.connection.readyState); const token = await RefreshToken.find() console.log(token) } catch (err) { console.error("testGetToken() err = " + err) throw err; } }
如果后续有多个定时脚本需要访问数据库,可以将连接初始化、异常捕获、自动关闭连接的逻辑封装为公共工具函数,减少重复代码。
内容的提问来源于stack exchange,提问作者JBW
相关产品推荐
相关产品推荐

