Next.js中MongoDB数据库对象创建及导出为null问题排查
问题
我按照MongoDB官方教程在Next.js应用中配置MongoDB,原配置文件mongodb-config.js导出dbPromise,在API中通过其then方法获取数据库实例db。为简化流程,我修改配置文件,想在dbPromise resolved后赋值给db并直接导出,但导入后db始终为null。
原配置文件代码
import { MongoClient } from 'mongodb' const uri = process.env.MONGODB_URI const options = { useUnifiedTopology: true, useNewUrlParser: true, } let client; let dbPromise; if (!process.env.MONGODB_URI) { throw new Error('Please add your Mongo URI to .env.local') } client = new MongoClient(uri, options) dbPromise = client.connect() export default dbPromise
原API使用代码
import dbPromise from "database/mongodb-config"; let db; dbPromise.then((value) => { const client = value; db = client.db("database_name"); }) .catch((error)=>{ console.error(error); });
修改后的配置文件代码
client = new MongoClient(uri, options) dbPromise = client.connect() let db; dbPromise.then((value)=>{ const client = value; db = client.db("datatbase_name"); }) .catch((error)=>{ console.error(error); }); export default db
原因
JavaScript模块导出的是值的快照:模块加载完成时,db的初始值是null,这个null会被作为导出值固定下来。后续dbPromise.then里的异步赋值只会改变模块内部的db变量,不会更新已经导出的那个值,所以外部导入后拿到的始终是初始的null。
解决方法
方法1:导出封装好的数据库实例Promise
直接在配置文件里导出包含数据库实例的Promise,外部可直接用await或then获取,比原写法更简洁:
import { MongoClient } from 'mongodb' const uri = process.env.MONGODB_URI const options = { useUnifiedTopology: true, useNewUrlParser: true, } if (!process.env.MONGODB_URI) { throw new Error('Please add your Mongo URI to .env.local') } const client = new MongoClient(uri, options) // 直接导出包含db实例的Promise export const dbPromise = client.connect().then(client => client.db("database_name"))
API中使用示例:
import { dbPromise } from "database/mongodb-config"; export default async function handler(req, res) { const db = await dbPromise; // 后续操作数据库 }
方法2:导出获取数据库实例的缓存函数
如果需要更灵活的控制,可导出一个带缓存的函数,避免重复创建连接:
import { MongoClient } from 'mongodb' const uri = process.env.MONGODB_URI const options = { useUnifiedTopology: true, useNewUrlParser: true, } if (!process.env.MONGODB_URI) { throw new Error('Please add your Mongo URI to .env.local') } let client; let db; async function getDb() { if (db) return db; if (!client) { client = new MongoClient(uri, options); await client.connect(); } db = client.db("database_name"); return db; } export default getDb;
API中使用示例:
import getDb from "database/mongodb-config"; export default async function handler(req, res) { const db = await getDb(); // 后续操作数据库 }
内容的提问来源于stack exchange,提问作者Rongeegee
相关产品推荐
相关产品推荐

