从 MongoClient.connect() 导出未在其他模块中读取
Posted
技术标签:
【中文标题】从 MongoClient.connect() 导出未在其他模块中读取【英文标题】:Export from MongoClient.connect() is not being read in other module 【发布时间】:2021-09-17 07:11:45 【问题描述】:我正在尝试在另一个模块中重用我的 MongoClient 连接,并且在导入时导出为 null。
index.js
import app from './server.js'
import pkg from 'mongodb'
const MongoClient = pkg
let db = null
async function listDatabases(client)
try
const dbList = await client.db().admin().listDatabases()
console.log('Databases:')
dbList.databases.forEach((db) =>
console.log(` - $db.name`) // I see the databases here
)
catch (error)
console.error(error)
MongoClient.connect(uri,
useNewUrlParser: true,
poolSize: 50,
useUnifiedTopology: true,
)
.then(async (client) =>
listDatabases(client) // I see the databases here
db = client
app.listen(port, () =>
console.log(`listening on port $port`)
)
)
.catch((err) =>
console.error(err.stack)
process.exit(1)
)
export default db
然后在 OrdersDAO.js 中,我正在导入 db 以便能够访问 db 和集合。我提到了这个***
import db from '../index.js'
static async getOrders()
try
// db is null here
console.log('OrdersDAO.getOrders ~~~ made it to the OrdersDAO step 2', db)
catch (e)
console.error(`OrdersDAO ~~~ Unable to get orders: $e`)
return e
我做错了什么?
下面是我原来的异步函数和后续函数调用:index.js
const client = new MongoClient(uri,
useNewUrlParser: true,
poolSize: 50,
useUnifiedTopology: true,
)
async function connectToMongoDB()
try
await listDatabases(client)
app.listen(port, () =>
console.log(`listening on port $port`)
)
catch (e)
console.error(`Index.js ~~~ Unable to get database.collection: $e`)
finally
console.log('Mongo Connection is closing ~~~~')
await client.close()
connectToMongoDB().catch(console.error)
【问题讨论】:
【参考方案1】:连接到数据库是一个异步操作,因此,它返回一个Promise
。该函数内分配的任何内容只有在该承诺解决后才可用。但是,您将返回 db
对象 在承诺之外,因此 js 引擎不会等待,而是返回初始值,即 null。
这是我在最近的一个项目中实现的一个简洁的解决方案,它还考虑了连接超时:
db.js:
const MongoClient = require("mongodb");
const DATABASE_URL = require("./config");
async function connect()
const client = await MongoClient.connect(DATABASE_URL,
useNewUrlParser: true
);
const db = client.db();
return client, db ;
;
module.exports = connect, dbHelper: connect()
crud.js:
const dbHelper, connect = require("./db");
async function reconnect()
return connect();
;
async function getConnectionOrReconnect()
let mongo = await Promise.resolve(dbHelper);
if (!mongo.client.isConnected()) mongo = await reconnect();
return mongo;
//other api functions here
在这里,我同时导出连接函数本身和连接结果(作为承诺)。与其他文件相比,我正在解析导入的连接,如果它超时,我将再次重新连接。
【讨论】:
但是通过连接池,我不应该每次需要客户端时都重新连接。? 这只是一个额外的好处(我从我的项目中复制粘贴它,由于某种原因我没有使用池)。重点是 db 对象从 db.js 文件中的 connect 函数内部作为 Promise 导出的方式,然后在另一个文件中解析。以上是关于从 MongoClient.connect() 导出未在其他模块中读取的主要内容,如果未能解决你的问题,请参考以下文章
NodeJS - MongoClient.Connect 与数据库的 URL 不是默认的
DeprecationWarning: current URL string parser is deprecated解决方法