mongoose.connection.once('open') 回调从不触发

mongoose.connection.once('open') callback never firing

我目前正在使用 Next.js 设置自定义节点服务器。我使用 Next.js 的事实应该不会有任何区别。

在以前的应用程序中,我总是使用 mongoose.connection.once('open', callback) 只有在数据库打开时才开始监听。这次不行了。

这是我的连接配置文件:

import mongoose from 'mongoose';
import { MONGO_URI } from '../constants'; // looks like 'mongodb://localhost/my-db' in development

mongoose
    .connect(MONGO_URI, () => {
        try {
            console.log(`Connected to ${MONGO_URI} with Mongoose.`);
        } catch (err) {
            throw err;
        }
    })

export default mongoose.connection;

我正在导入它并在我的 main.ts 文件中使用它,如下所示:

import express from 'express';
import next from 'next';

import * as dotenv from 'dotenv';
import logger from 'morgan';
import compression from 'compression';
import helmet from 'helmet';

import rateLimiter from './config/rateLimiter';
import db from './config/connection'; // This is the config file

dotenv.config();

const PORT = process.env.PORT || '8000';
const dev = process.env.NODE_ENV !== 'production';

const nxt = next({ dev });
const handle = nxt.getRequestHandler();

nxt.prepare().then(() => {
    const app = express();

    app.enable('trust proxy');

    app.use(logger('dev'));
    app.use(helmet());
    app.use(rateLimiter);
    app.use(compression());
    app.use(express.urlencoded({ extended: false }));
    app.use(express.json());

    db.once('open', () => {
        app.listen(PORT, () => {
            // This log never happens
            console.log(`Listening on port ${PORT}.`);
        });
    });
});

这非常奇怪,因为“Connected to mongodb://localhost/my-db with Mongoose.实际上在使用上面的代码时被记录,但是 express 应用程序根本不听;但是,当我从 db.once 回调函数中删除 app.listen 时,“Listening on port 8000”当然会被记录下来。

我被难住了。 为什么 'open' 事件没有触发? 我已经通过 Mongo shell 验证 mongo 在本地工作,并且当我将这些文件所在的文件夹 (server) 与 Next.js 应用程序分开时(当我还在争论要编写哪种类型的视图层时),同样的代码正在工作。

问题不是兼容性。我是运行Mongo5.0.5,Mongoose 6.2.5,应该是根据this

找的

请不要link其他问题。 None 其中有帮助:

@Shivam Sood 的评论是正确的。 db.once('open') 被调用得太晚了。一旦 nxt.prepare 发生,数据库就已经打开了。

修改后的代码如下:

import express from 'express';
import next from 'next';
import * as dotenv from 'dotenv';

import logger from 'morgan';
import compression from 'compression';
import helmet from 'helmet';

import rateLimiter from './config/rateLimiter';
import db from './config/connection';

dotenv.config();

const PORT = process.env.PORT || '8000';
const dev = process.env.NODE_ENV !== 'production';

const nxt = next({ dev });
const handle = nxt.getRequestHandler();

db.once('open', () => { // Listen for 'open' event before nxt.prepare, and before listening on PORT
    nxt.prepare().then(() => {
        const app = express();

        app.enable('trust proxy');

        app.use(logger('dev'));
        app.use(helmet());
        app.use(rateLimiter);
        app.use(compression());
        app.use(express.urlencoded({ extended: false }));
        app.use(express.json());

        app.get('*', (req, res) => {
            return handle(req, res);
        });

        app.listen(PORT, () => {
            console.log(`Listening on port ${PORT}.`);
        });
    });
});