MongoDB 4.1下使用Singleton单例存储连接池报reference undefined如何解决
MongoDB单例调用报错问题分析与解决
错误原因
- 核心问题出在
MongoInstance类的dbgetter逻辑缺陷:当数据库未完成初始化时,getter的else分支只触发了异步的connect()方法,没有将connect()返回的Promise对象作为getter的返回值,此时MongoInstance.db的取值为undefined,调用侧的await MongoInstance.db实际是在等待undefined,无法阻塞到连接完成,自然无法读取到collection属性。 - 次要问题是
dbgetter的返回值类型不统一,初始化完成前调用无有效返回值,初始化完成后返回db实例,导致调用逻辑不稳定。
解决方案
方案一:调整getter逻辑,统一返回Promise(无需修改调用代码)
修改MongoInstance类的db getter,不管是否初始化都返回Promise,保证调用侧的await逻辑可以正常工作:
static get db() { if (MongoInstance.isInitialized()) { // 已初始化的场景直接返回包装为resolve状态的db实例 return Promise.resolve(MongoInstance._db); } else { // 未初始化的场景返回连接Promise,连接完成后返回db实例 return MongoInstance.connect().then(() => MongoInstance._db); } }
调整后原调用侧的代码不需要做任何修改,即可正常获取db实例执行查询。
方案二:应用启动阶段预初始化连接(更推荐,性能和稳定性更好)
在应用启动入口处就主动等待数据库连接完成,再启动后续业务逻辑,避免业务请求阶段才触发连接,同时可以提前暴露连接异常:
// 应用入口文件示例 const MongoInstance = require('./../database/mongodb'); async function startApp() { // 先等待数据库连接完成 await MongoInstance.connect(); // 后续启动服务、注册路由等业务逻辑 } startApp();
该方案下原db getter不需要修改,业务调用时数据库已经完成初始化,可以直接同步返回db实例,性能更好。
内容的提问来源于stack exchange,提问作者mtnp
相关产品推荐
相关产品推荐

