请教大家一下,我再新书Nodejs实战出现的问题

请教大家一下,我再新书Nodejs实战出现的问题

Error: db object already connecting, open cannot be called multiple times

我不知道哪里出了问题,这是node.js实战第一章出现的问题

7 回复

当然可以!让我们来分析一下你遇到的错误信息,并提供一些可能的解决方案。

错误信息

Error: db object already connecting, open cannot be called multiple times

分析

这个错误通常出现在你尝试多次打开同一个数据库连接对象时。在 Node.js 中,当你使用 MongoDB 等数据库时,通常会创建一个全局的数据库连接对象。如果你在不同的地方多次调用 open 方法,就会抛出这个错误。

示例代码

假设你在书中使用了 mongodb 这个库来操作数据库,以下是一个常见的错误示例:

const MongoClient = require('mongodb').MongoClient;

// 假设这是一个全局变量
let db;

async function connectToDatabase() {
    if (!db) {
        db = await MongoClient.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });
        console.log("Connected to the database");
    }
}

// 在多个地方调用这个函数
connectToDatabase();
connectToDatabase();

在这个例子中,尽管我们检查了 db 是否已经存在,但仍然可能会因为异步操作而出现问题。因此,更好的做法是确保只初始化一次数据库连接。

解决方案

我们可以使用一个标志来确保只初始化一次数据库连接:

const MongoClient = require('mongodb').MongoClient;

let db;
let isConnecting = false;

async function connectToDatabase() {
    if (isConnecting || db) return db; // 如果已经在连接或已经连接,则直接返回

    isConnecting = true;
    try {
        db = await MongoClient.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });
        console.log("Connected to the database");
    } finally {
        isConnecting = false;
    }

    return db;
}

// 使用示例
(async () => {
    await connectToDatabase();
    const collection = db.collection('mycollection');
    // 进行其他数据库操作
})();

解释

  1. 标志变量:我们引入了一个 isConnecting 变量来跟踪当前是否正在进行数据库连接。
  2. 条件判断:在 connectToDatabase 函数中,我们首先检查 isConnectingdb 是否已经存在。如果存在,则直接返回已有的 db 对象。
  3. 异步操作:在实际的数据库连接过程中,我们将 isConnecting 设置为 true,并在连接完成后设置回 false
  4. 返回值:函数返回 db 对象,以便在其他地方使用。

这样可以确保数据库连接只初始化一次,避免重复调用 open 方法导致的错误。希望这能帮助你解决问题!


你就截这么一小段,你自己看看是不是书上内容和实际版本有问题,express也经历了不少改动。

就是数据库已经连接了。。。 他好像每次请求数据库都建立链接了是吗,一个进程只要连一次数据库就好了,除非你断开了

这个错误 一般就是代码块闭合 写错了 就是这个 “}”写错地方了,仔细检查下代码

这是db.js var settings = require(’…/settings’), Db = require(‘mongodb’).Db, Connection = require(‘mongodb’).Connection, Server = require(‘mongodb’).Server; module.exports = new Db(settings.db, new Server(settings.host, Connection.DEFAULT_PORT),{safe: true});

这是user.js var mongodb = require(’./db’);

function User(user){ this.name = user.name; this.password = user.password; this.email = user.email; };

module.exports = User;

User.prototype.save = function(callback){ var user = { name: this.name, password: this.password, email: this.email };

mongodb.open(function(err, db){
	if (err){
		mongodb.close();
		return callback(err);
	}
	db.collection('users',function(err, collection){
		if (err){
			mongodb.close();
			return callback(err);
		}
		collection.insert(user, {
			safe: true
		}, function(err, user){
			mongodb.close();
			if (err){
				return callback(err);
			}
			callback(null, user[0]);
		});
	});
});

};

User.get = function(name, callback){ mongodb.open(function(err,db){ if (err){ return callback(err); } db.collection(‘users’, function (err, collection) { if (err) { mongodb.close(); return callback(err); } collection.findOne({ name: name },function (err,user) { if (err) { return callback(err) } callback(null,user); }); }); }); };

根据你提供的错误信息 Error: db object already connecting, open cannot be called multiple times,这表示你在尝试多次打开同一个数据库连接对象。在 Node.js 中,数据库连接对象通常只能打开一次,再次调用 open 方法会导致错误。

解决方法

  1. 确保只打开一次数据库连接:你需要检查代码中是否有重复调用 db.open() 的地方。
  2. 使用连接池(如果适用):如果你的应用需要频繁地访问数据库,可以考虑使用数据库连接池来管理连接。

示例代码

假设你正在使用 mongodb 驱动程序:

const MongoClient = require('mongodb').MongoClient;

let db;

async function connectToDatabase() {
    if (db) {
        console.log("Database connection already established.");
        return;
    }

    const uri = "your_mongodb_connection_string_here";
    const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

    try {
        await client.connect();
        db = client.db('your_database_name');
        console.log("Connected successfully to the database");
    } catch (error) {
        console.error("Failed to connect to the database", error);
    }
}

// 使用连接
async function someFunction() {
    await connectToDatabase();
    // 在这里使用 db 对象
    const collection = db.collection('your_collection');
    // ...
}

解释

  • connectToDatabase 函数:这是一个异步函数,用于连接到 MongoDB 数据库。它会检查是否已经存在数据库连接,如果不存在,则建立新的连接并存储在全局变量 db 中。
  • someFunction 函数:这是另一个示例函数,在其中我们调用 connectToDatabase 来确保已经建立了数据库连接,然后我们可以安全地使用 db 对象进行其他操作。

这样可以避免重复调用 db.open() 引起的错误,并确保每次只需要连接一次数据库。

回到顶部