Je to proto, že kód obsahuje anti-vzor:pokaždé, když přijde nový požadavek, otevře nové připojení k databázi a poté, co byla odpověď odeslána, toto připojení zavře. Následně se pokusil znovu použít uzavřené připojení, proto se zobrazila chybová zpráva, kterou vidíte u 2. požadavku.
Co chcete, je připojit se k databázi pouze jednou po celou dobu životnosti aplikace pomocí objektu globálního připojení a poté tento globální objekt použít k provádění operací s databází.
Použití tohoto globálního objektu umožňuje ovladači MongoDB správně vytvořit fond připojení k databázi. Tento fond je spravován ovladačem MongoDB a vyhýbá se drahému vzoru připojení/opětovného připojení.
Například:
// 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))
})
})
Upravit odpovědět na vaši otázku v komentáři:
Je to proto, že v původním kódu dbClient
byla definována globálně. Když dbClient.close()
byl volán, globální dbClient
bylo zavřeno. Při tomto dbClient
došlo k chybě objekt byl znovu použit. Důvodem je connect()
vytvoří fond připojení namísto jednoho připojení a neočekávalo se, že bude voláno vícekrát za vyvolání.
Pokud přesunete dbClient
proměnnou z globálního rozsahu do app.get()
kontextu, zjistíte, že při opakovaném volání koncového bodu HTTP jako nového dbClient
nedojde k žádné chybě. objekt byl vytvořen pokaždé.
Ačkoli to bude fungovat, není to doporučený vzor. Je lepší použít vzor podobný příkladu kódu, který jsem zveřejnil výše.