为什么MongoDB连接成功后调用getDb时_db变量仍显示未定义?
问题根因
这是典型的异步执行时序问题,不存在遗漏配置:MongoClient.connect是异步IO操作,你调用mongoConnect之后,数据库连接还没建立完成、_db还没完成赋值的时候,就提前调用了Product.save()方法触发getDb(),此时_db还是初始的undefined状态,自然会抛出错误。你在控制台看到的connected日志是异步操作完成后才输出的,时序上晚于你提前调用save的时间。
解决方法
方案1:把所有数据库操作放到mongoConnect的回调中执行
保证所有涉及getDb()的逻辑触发时,_db已经完成赋值,入口文件示例:
const { mongoConnect } = require('./Util/database'); const Product = require('./models/Product'); mongoConnect(() => { // 所有涉及数据库操作的逻辑必须写在这个回调内部 const product = new Product('测试商品', 99, '测试描述'); product.save() .then(() => console.log('商品保存成功')) .catch(err => console.log(err)); });
方案2:改造成Promise+async/await写法(推荐,避免回调嵌套)
先修改database.js中的mongoConnect方法,让它直接返回Promise:
const mongoConnect = () => { return MongoClient.connect('mongodb+srv://pawan:*************@cluster0.vchvo.mongodb.net/myFirstDatabase?retryWrites=true&w=majority') .then(client => { console.log('connected'); _db = client.db(); }) .catch(err => { console.log(err); throw err; }) }
入口文件用async/await调用:
const { mongoConnect } = require('./Util/database'); const Product = require('./models/Product'); const initApp = async () => { try { // 等待数据库连接完成再执行业务逻辑 await mongoConnect(); const product = new Product('测试商品', 99, '测试描述'); await product.save(); console.log('商品保存成功'); } catch (err) { console.log('应用启动失败', err); } } initApp();
内容的提问来源于stack exchange,提问作者Pawan
相关产品推荐
相关产品推荐

