Това е така, защото кодът съдържа анти-модел:всеки път, когато влезе нова заявка, той отваря нова връзка към базата данни, след което затваря тази връзка, след като отговорът е изпратен. След това впоследствие се опита да използва отново затворената връзка, оттук и съобщението за грешка, което виждате при втората заявка.
Това, което искате, е да се свържете само веднъж към базата данни за целия живот на приложението, като използвате обект за глобална връзка, след което да използвате този глобален обект, за да извършвате операции с базата данни.
Използването на този глобален обект позволява на драйвера 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()
контекст, ще откриете, че няма да се генерира грешка, когато извикате HTTP крайната точка няколко пъти, като нов dbClient
обект е създаван всеки път.
Като каза това, въпреки че ще работи, това не е препоръчителен модел. По-добре е да използвате модел, подобен на примерния код, който публикувах по-горе.