在nodejs上使用mongodb驱动程序时,MongoClient的连接未关闭

时间:2019-10-10 00:30:00

标签: node.js mongodb

说明

当我在打开的client.close()上调用MongoClient并使用client.isConnected()检查连接状态时,连接状态仍显示为true(client.isConnected()返回true)

复制步骤

MongoConfiguration.ts文件

import { MongoClient } from 'mongodb';

export default class MongoConfiguration {
  private _client: MongoClient;
  get client(): MongoClient {
    return this._client;
  }

  constructor() {
    const uri = `mongodb://${hostname}:${port}`;
    this._client = new MongoClient(uri);
  }

  public connectClient= async () => {
    try {
      console.log('Connecting to mongoDB');
      await this._client.connect();
    } catch (err) {
      await this.disconnectClient();
      throw err;
    }
  };

  public disconnectClient= async () => {
    try {
      await this._client.close();
      console.log('Connection to MongoDB closed');
    } catch (err) {
      throw err;
    }
  };

测试文件

import { describe } from 'mocha';
import { expect } from 'chai';
import MongoConfiguration from './MongoConfiguration';
import { MongoClient } from 'mongodb';

describe('Test mongo client connection', () => {
  let mongoConfiguration: MongoConfiguration;
  let client: MongoClient;

  before(() => {
    mongoConfiguration = new MongoConfiguration();
    client = mongoConfiguration.client;
  });

  it('should connect and close connection successfully', async () => {
    await mongoConfiguration.connectClient();
    expect(client.isConnected()).equals(true);
    await mongoConfiguration.disconnectClient();
    expect(client.isConnected()).equals(false);
  });
});

预期结果

测试成功通过

实际结果

测试失败,因为最后一个client.isConnected()仍然是true

使用的包裹

"devDependencies": {
    "@types/chai": "^4.2.3",
    "@types/mocha": "^5.2.7",
    "chai": "^4.2.0",
    "mocha": "^6.2.1",
    "nodemon": "^1.19.3",
    "reflect-metadata": "^0.1.13",
    "ts-node-dev": "^1.0.0-pre.43"
  },
  "dependencies": {
    "@types/express": "^4.17.1",
    "@types/mongodb": "^3.3.5",
    "express": "^4.17.1",
    "mongodb": "^3.3.2",
    "typescript": "^3.6.3"
  }

据我所知,这应该很简单,但我想我做错了(或很多事情)。那么,请问关闭mongodb连接的正确方法是什么?

编辑

我尝试在测试中添加超时,以等待几秒钟,以查看连接是否确实关闭,但是client.isConnected()仍然为true

新测试

it('should connect and close connection successfully', async () => {
    await mongoConfiguration.connectMongoClient();
    expect(client.isConnected()).equals(true);
    await mongoConfiguration.closeMongoClient();
    setTimeout(() => console.log(client.isConnected()), 5000); // Logs true
  });

我开始怀疑连接是否会关闭并且github链接不支持打开问题

1 个答案:

答案 0 :(得分:0)

Mongodb驱动器官方doc说,close函数就像一个回调样式函数,如果没有传递回调,它只会返回一个伪Promise。源代码lib/mongo_client.js, line 310。这意味着await关键字无助于连接断开。

await mongoConfiguration.disconnectClient();
expect(client.isConnected()).equals(false);

client.isConnected()await mongoConfiguration.disconnectClient();行之后立即执行,而await this._client.close();仍未“完成”,则client.isConnected()将是true

解决方案,将this._client.close()转换为诺言。

  public disconnectClient = async () => {
    try {
      await new Promise((resolve, reject) => { // wait until it finish the `close` job
        this._client.close((error) => {
          if (error) {
            return reject(error);
          }
          resolve();
        });
      });
      console.log('Connection to MongoDB closed');
    } catch (err) {
      throw err;
    }
  };