0

我将connect-mongo用于我的 ExpressJS 会话存储和Mongoose用于我的数据库连接,并且我将称之为时间问题。这是我的代码:

dbservice.js

const mongoose = require('mongoose');
const debug = require('debug')('app:core:db:service');
const chalk = require('chalk');
const config = require('config');

const mongoDbUrl = config.mongodb_url;

const mongoDbOptions = {
  useUnifiedTopology: true,
  useNewUrlParser: true,
  useCreateIndex: true,
  useFindAndModify: false,
};
(async () => {
  try {
    await mongoose.connect(mongoDbUrl, mongoDbOptions);
    debug(`Connected to ${chalk.green('MongoDB')}`);
  } catch (err) {
    debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
  }
})();
const db = mongoose.connection;
db.on('error', (err) => {
  debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
});
// For nodemon restarts
process.once('SIGUSR2', () => {
  const msg = 'Nodemon Restart';
  db.close()
    .then(() => {
      debug(`${chalk.green('MongoDB')} connection ${chalk.red(`closed`)}: ${msg}`);
      process.kill(process.pid, 'SIGUSR2');
    })
    .catch((err) => {
      debug(err);
    });
});
const dbClient = db.getClient();

module.exports = dbClient;

app.js

const dbClient = require('dbService');

// Using Express Session with Google Cloud Datastore to securly store session/cookie information
app.use(
  session({
    // Using MongoDB as session store
    store: MongoStore.create({
      client: dbClient, // Use Mongoose for DB Conection
      ttl: 1800000, // Ages session out at 30 minutes
      autoRemove: 'native', // Uses MongoDB's native Time to Live (TTL) to expire and remove records
      },
    }),
  }),
);

此代码在使用本地网络上的 MongoDB 实例时效果很好,因为连接到 MongoDB 的延迟非常小,它可以工作。但是,使用 MongoDB Atlas 时,连接会有一到两秒的延迟。所以,我怀疑(我认为很棒)我的代码行const dbClient = db.getClient()失败dbservice.jsconnect-mongo抛出错误:

(node:1148) UnhandledPromiseRejectionWarning: MongoError: MongoClient must be connected before calling MongoClient.prototype.db` because Mongoose is not connected.

作为一个新手,我一直在努力尝试解决这个问题。我试图找到一种方法来mongoose.connection.readyState等待它返回一个1for connected 但失败了。

我的问题是:有没有更好的方法让我正确地返回dbClient它以等待 Mongoose 连接到 MongoDB?任何帮助是极大的赞赏。

4

2 回答 2

1

您没有从 dbservice.js 返回 Promise

(async () => {})()

对异步代码没有意义

你的代码应该是什么样子

const getDbClient = async () => {
  try {
    await mongoose.connect(mongoDbUrl, mongoDbOptions);
    debug(`Connected to ${chalk.green('MongoDB')}`);
    const db = mongoose.connection;
    return db.getClient()
  } catch (err) {
    debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
  }
}

function async start() {
  const client = await getDbClient()
    // Using Express Session with Google Cloud Datastore to securly store session/cookie         information
  app.use(
    session({
      // Using MongoDB as session store
      store: MongoStore.create({
        client: client, // Use Mongoose for DB Conection
        ttl: 1800000, // Ages session out at 30 minutes
        autoRemove: 'native', // Uses MongoDB's native Time to Live (TTL) to expire and        remove records
        },
      }),
    }),
  );
  // Here is server startup code.... app.listen etc.
}

start.then(() => console.log('started'))

于 2021-07-08T11:37:55.153 回答
0

Nikita Mazur的回应中得到提示,我修改dbservices.js了以下内容:

const mongoose = require('mongoose');
const debug = require('debug')('app:core:db:service');
const chalk = require('chalk');
const { mongoDbUrl } = require('../config/config');

const mongoDbOptions = {
  useUnifiedTopology: true,
  useNewUrlParser: true,
  useCreateIndex: true,
  useFindAndModify: false,
};
async function dbConnection() {
  try {
    await mongoose.connect(mongoDbUrl, mongoDbOptions);
    debug(`Connected to ${chalk.green('MongoDB')}`);
  } catch (err) {
    debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
  }
  return mongoose.connection.getClient();
}
const db = mongoose.connection;
db.on('error', (err) => {
  debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
});
// For nodemon restarts
process.once('SIGUSR2', () => {
  const msg = 'Nodemon Restart';
  db.close()
    .then(() => {
      debug(`${chalk.green('MongoDB')} connection ${chalk.red(`closed`)}: ${msg}`);
      process.kill(process.pid, 'SIGUSR2');
    })
    .catch((err) => {
      debug(err);
    });
});

module.exports = dbConnection();
于 2021-07-20T14:25:46.643 回答