如何在使用数据库之前等待建立 MongoDB 连接

How to Wait Until a MongoDB Connection is Made before Using the Database

我有以下代码来创建到我的 MongoDB 数据库的连接,并存储它以备将来使用。

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

// The database will be defined once a connection to between the cluster and mongodb is created
let _database;

const uri = '';
const databaseName = 'db';

const mongoConnect = () => {
    MongoClient.connect(uri)
        .then((client) => {
            _database = client.db(databaseName);
        })
        .catch((err) => {
            console.log(err);
            throw err;
        });
};

const getDb = () => {
    if (_database) {
        return _database;
    }
    throw 'No database found!';
};

module.exports = {
    mongoConnect,
    getDb
}

我的问题是在建立连接之前 _database 是未定义的。如果我的网站在定义 _database 之前尝试使用数据库,它将引发错误并崩溃。

我想这样做而不是崩溃,我的代码的其他部分只会等到 _database 不是未定义的。听起来需要一个 await/async 解决方案,但我不能全神贯注于如何在此处实现类似的解决方案。任何建议都会很棒!

第一种方法:使 mongoConnect 成为异步函数并在执行任何剩余代码之前等待它。

const mongoConnect = async () => {
    try {
        const client = await MongoClient.connect(uri);
        _database = client.db(databaseName);
    } catch(e) {
        console.log(err);
        throw err;
    }
};

在您的代码开头

await mongoConnect();
//Remaning code here

第二种方法:让 getDb 函数等待直到数据库连接可用

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

const uri = '';
const databaseName = 'db';

const databasePromise = new Promise((resolve, reject) => {
    MongoClient.connect(uri)
    .then((client) => {
        resolve(client.db(databaseName));
    })
    .catch((err) => {
        reject(err);
    });
})

const getDb = async () => {
    return await databasePromise;
};

module.exports = {
    getDb
}

示例代码 运行 并检查第二种方法:

const databasePromise = new Promise((resolve) => {
    console.log("Connecting to db in 5 seconds...")
    setTimeout(() => {
        console.log("Done")
        resolve("done")
    }, 5000)
})

const getDb = async () => {
    return await databasePromise;
};

console.time("First_getDb_call")
getDb().then(res => {
    console.timeEnd("First_getDb_call")
    console.log(res)
    console.time("Second_getDb_call")
    getDb().then(res => {
        console.timeEnd("Second_getDb_call")
        console.log(res)
    })
})

**非常简单的方法**只需在 MongoClient.connect 函数之前添加 await 并使函数异步 现在它将等待连接有响应然后继续前进。

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

// The database will be defined once a connection to between the cluster 
and mongodb is created
let _database;

const uri = 'mongodb://localhost:27017/mydb';
const databaseName = 'db';

const mongoConnect = async () => {
await MongoClient.connect(uri)
    .then((client) => {
        _database = client.db(databaseName);
    })
    .catch((err) => {
        console.log(err);
        throw err;
    });
 };

const getDb = () => { 
  if (_database) {
    return _database;
}
throw 'No database found!'; 
};



module.exports = {
  mongoConnect,
  getDb
}