Nodejs中db object already connecting, open cannot be called multiple times
Nodejs中db object already connecting, open cannot be called multiple times
使用的版本 { “name”: “microblog”, “version”: “0.0.1”, “private”: true, “scripts”: { “start”: “node ./bin/www” }, “dependencies”: { “express”: “~4.2.0”, “static-favicon”: “~1.0.0”, “morgan”: “~1.0.0”, “cookie-parser”: “~1.0.1”, “body-parser”: “~1.0.0”, “debug”: “~0.7.4”, “ejs”: “~0.8.5”, “connect-mongo” : “>=0.1.7”, “mongodb”: “", “connect-flash”: "” } } db object already connecting, open cannot be called multiple times undefined
Error: db object already connecting, open cannot be called multiple times at Db.open (D:\node\microblog\node_modules\mongodb\lib\mongodb\db.js:257:11) at User.save (D:\node\microblog\models\user.js:18:10) at Object.module.exports [as handle] (D:\node\microblog\routes\index.js:51:10) at next_layer (D:\node\microblog\node_modules\express\lib\router\route.js:103:13) at Route.dispatch (D:\node\microblog\node_modules\express\lib\router\route.js:107:5) at D:\node\microblog\node_modules\express\lib\router\index.js:205:24 at Function.proto.process_params (D:\node\microblog\node_modules\express\lib\router\index.js:269:12) at next (D:\node\microblog\node_modules\express\lib\router\index.js:199:19) at next_layer (D:\node\microblog\node_modules\express\lib\router\route.js:77:14) at next_layer (D:\node\microblog\node_modules\express\lib\router\route.js:81:14)
Node.js 中 db object already connecting, open cannot be called multiple times
问题
背景
当你在 Node.js 应用程序中使用 MongoDB 时,可能会遇到错误信息 db object already connecting, open cannot be called multiple times
。这通常是因为你尝试多次打开同一个数据库连接对象。
原因
这个问题通常发生在以下几种情况:
- 在应用启动时初始化数据库连接。
- 在多个地方或多次尝试打开同一个数据库连接。
解决方案
为了解决这个问题,你可以采用以下策略:
- 确保只初始化一次数据库连接:创建一个全局的数据库连接实例,并在整个应用程序中重用它。
- 使用连接池:MongoDB 的官方驱动支持连接池,这可以提高性能并避免重复连接的问题。
示例代码
首先,安装 MongoDB 驱动:
npm install mongodb
然后,在你的应用程序中进行如下调整:
// 初始化数据库连接
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017/myproject';
let db;
async function connectDb() {
if (!db) {
db = await MongoClient.connect(url, { useNewUrlParser: true, useUnifiedTopology: true });
console.log("Connected successfully to server");
}
return db;
}
module.exports = connectDb;
接下来,在你的路由或其他服务中使用这个连接:
const express = require('express');
const connectDb = require('./db');
const app = express();
app.get('/users', async (req, res) => {
const db = await connectDb();
const collection = db.collection('users');
const users = await collection.find({}).toArray();
res.json(users);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解释
connectDb
函数:这个函数负责连接到 MongoDB 并返回数据库实例。我们使用if (!db)
来检查是否已经连接过,如果已经连接过,则不再重新连接。await connectDb()
:在需要使用数据库的地方,调用connectDb()
函数来获取数据库连接实例。
通过这种方式,你可以确保数据库连接只被初始化一次,并且在整个应用程序中重用该连接。这样就能避免重复连接导致的错误。
你一定是在某个require的module中再次调用了db.open了,记得先调用db.close()
谢谢,问题解决了,函数嵌套的逻辑错了,
在Node.js中使用MongoDB时,如果你尝试多次打开同一个数据库连接(即调用db.open()
多次),将会抛出“db object already connecting, open cannot be called multiple times”的错误。这是因为MongoDB驱动程序不允许多次初始化同一个数据库对象。
为了避免这种错误,你可以确保只创建一次数据库连接,并在整个应用程序中复用它。这里有一个简单的示例,展示了如何设置一个单一的数据库连接:
const MongoClient = require('mongodb').MongoClient;
let db;
function connectDb() {
return new Promise((resolve, reject) => {
if (!db) { // 如果尚未建立连接,则创建新的连接
MongoClient.connect('mongodb://localhost:27017/microblog', { useNewUrlParser: true, useUnifiedTopology: true })
.then(client => {
db = client.db();
console.log("Connected correctly to server");
resolve(db);
})
.catch(err => {
reject(err);
});
} else { // 如果已经建立了连接,则直接返回现有的连接
resolve(db);
}
});
}
// 在你的应用中使用
connectDb().then(() => {
// 现在你可以使用 `db` 对象来执行数据库操作
}).catch(err => {
console.error("Error connecting to database", err);
});
在这个例子中,我们定义了一个全局变量db
来存储数据库连接实例。connectDb
函数检查db
是否已经被初始化,如果没有,则创建一个新的连接。如果已经存在,则直接返回现有的连接。这可以防止在同一进程中重复打开数据库连接。
通过这种方式,你可以确保数据库连接在你的整个应用生命周期中只被打开一次,并且可以在任何需要的地方安全地使用db
对象。