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)


4 回复

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。这通常是因为你尝试多次打开同一个数据库连接对象。

原因

这个问题通常发生在以下几种情况:

  1. 在应用启动时初始化数据库连接。
  2. 在多个地方或多次尝试打开同一个数据库连接。

解决方案

为了解决这个问题,你可以采用以下策略:

  1. 确保只初始化一次数据库连接:创建一个全局的数据库连接实例,并在整个应用程序中重用它。
  2. 使用连接池: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对象。

回到顶部