Это потому, что код содержит анти-шаблон: каждый раз, когда приходит новый запрос, он открывает новое соединение с базой данных, а затем закрывает это соединение после отправки ответа.Затем он впоследствии попытался повторно использовать закрытое соединение, отсюда и сообщение об ошибке, которое вы видите во втором запросе.
Вам нужно только один раз подключиться к базе данных на время существования приложения с использованием глобального соединения.затем используйте этот глобальный объект для выполнения операций с базой данных.
Использование этого глобального объекта позволяет драйверу MongoDB правильно создавать пул соединений с базой данных.Этот пул управляется драйвером MongoDB и позволяет избежать дорогостоящего шаблона подключения / переподключения.
Например:
// listen on this port
const port = 3000
// global database client object
var client = null
// listen on the configured port once database connection is established
MongoClient.connect('mongodb://localhost:27017', { useNewUrlParser: true }, (err, res) => {
assert.equal(null, err)
client = res
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
})
// use the client global object for database operations
app.get('/', (req, res) => {
db = req.query.db
col = req.query.col
client.db(db).collection(col).find({}).toArray((err, docs) => {
assert.equal(null, err)
res.send(JSON.stringify(docs))
})
})
Редактировать , чтобы ответить на ваш вопрос в комментарии:
Почему он пытается повторно использовать предыдущее соединение, когда я подключаюсь каждый раз?
Это потому, что в исходном коде dbClient
было определено глобально.Когда был вызван dbClient.close()
, глобальный dbClient
был закрыт.Затем возникла ошибка, когда этот объект dbClient
был повторно использован.Это связано с тем, что connect()
создает пул соединений вместо одного соединения, и не ожидалось, что он будет вызываться несколько раз за вызов.
Если переместить переменную dbClient
из глобальной области в app.get()
context, вы обнаружите, что при многократном вызове конечной точки HTTP ошибка не возникнет, поскольку каждый раз создается новый dbClient
объект.
Сказав, что, хотя это будет работать, этоэто не рекомендуемый шаблон.Лучше использовать шаблон, похожий на пример кода, который я выложил выше.