Det er 3 år siden, jeg stillede og besvarede spørgsmålet. Siden da har et par ting ændret sig. Her er den nye løsning baseret på ES6, mssql 4 og Express 4, som jeg vil foreslå i dag.
To nøgleelementer er på spil her.
- Moduler cachelagres efter første gang, de indlæses. Det betyder, at hvert kald til require('./db') vil returnere nøjagtigt det samme objekt. Det første krav fra db.js vil køre den fil og oprette løftet og eksportere det. Det andet krav til db.js vil returnere DET samme løfte uden at køre filen. Og det er det løfte, der vil løse sig med puljen.
- Et løfte kan bekræftes igen. Og hvis det løste før, vil det straks løses igen med det, det løste med første gang, hvilket er puljen.
I server.js
const express = require('express')
// require route handlers.
// they will all include the same connection pool
const set1Router = require('./routes/set1')
const set2Router = require('./routes/set2')
// generic express stuff
const app = express()
// ...
app.use('/set1', set1Router)
app.use('/set2', set2Router)
// No need to connect the pool
// Just start the web server
const server = app.listen(process.env.PORT || 3000, () => {
const host = server.address().address
const port = server.address().port
console.log(`Example app listening at http://${host}:${port}`)
})
I db.js
const sql = require('mssql')
const config = {/*...*/}
const poolPromise = new sql.ConnectionPool(config)
.connect()
.then(pool => {
console.log('Connected to MSSQL')
return pool
})
.catch(err => console.log('Database Connection Failed! Bad Config: ', err))
module.exports = {
sql, poolPromise
}
I routes/set1.js
og routes/set2.js
const express = require('express')
const router = express.Router()
const { poolPromise } = require('./db')
router.get('/', async (req, res) => {
try {
const pool = await poolPromise
const result = await pool.request()
.input('input_parameter', sql.Int, req.query.input_parameter)
.query('select * from mytable where id = @input_parameter')
res.json(result.recordset)
} catch (err) {
res.status(500)
res.send(err.message)
}
})
module.exports = router
For at opsummere
Du vil altid få det samme løfte på grund af modulcaching, og det løfte vil igen og igen løses med den pulje, det løste med første gang. Således bruger hver routerfil den samme pulje.
BTW:der er nemmere måder at gå om prøvefangsten på ekspresruten, som jeg ikke vil dække i dette svar. Læs om det her:https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
Den gamle løsning
Dette er den løsning, jeg postede for 3 år siden, fordi jeg troede, jeg havde et svar, der var værd at dele, og jeg kunne ikke finde en dokumenteret løsning andre steder. Også i nogle få numre (#118, #164, #165) på node-mssql diskuteres dette emne.
I server.js
var express = require('express');
var sql = require('mssql');
var config = {/*...*/};
//instantiate a connection pool
var cp = new sql.Connection(config); //cp = connection pool
//require route handlers and use the same connection pool everywhere
var set1 = require('./routes/set1')(cp);
var set2 = require('./routes/set2')(cp);
//generic express stuff
var app = express();
//...
app.get('/path1', set1.get);
app.get('/path2', set2.get);
//connect the pool and start the web server when done
cp.connect().then(function() {
console.log('Connection pool open for duty');
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
}).catch(function(err) {
console.error('Error creating connection pool', err);
});
I routes/set1.js
var sql = require('mssql');
module.exports = function(cp) {
var me = {
get: function(req, res, next) {
var request = new sql.Request(cp);
request.query('select * from test', function(err, recordset) {
if (err) {
console.error(err);
res.status(500).send(err.message);
return;
}
res.status(200).json(recordset);
});
}
};
return me;
};