在nodejs上使用mongodb驱动程序时,MongoClient的连接未关闭
说明
当我在打开的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连接的正确方法是什么?
回答如下: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; } };