用asynchronous初始化表示中间件

我正在写一些需要访问数据库的快递中间件。 它将作为一个包发布,所以我希望它是尽可能的自包含。 我想知道如何处理与数据库的连接。 它是asynchronous的(当然),但是只有在程序包初始化时才需要执行一次。 这发生在哪里?

我在想这样的事情 问题是,在数据库准备就绪之前,中间件会立即传回。

// App app.use(myMiddleware({ db: "<db connection string>" }); // Middleware module.exports = function(db) { // Open db return function(req, res, next) { // Middleware stuff } } 

我build议不要这样一个单身人士,dependency injection是一个更好的解决scheme,每个应用程序的连接是难以扩展的。 连接池可能是一个更好的主意。

这就是说,你可以做如下的事情:

 var db = null; // to keep our instance var asked = false; // to not make several requests that override each other function openDb(db,ready){ // if we already have it, we return the instance if(db !== null) ready(null,db); // if it was already asked by another instance, keep track of it // to avoid multiple requests. if(asked) asked.push(ready); asked = []; openDbCode(db,function(err,result){ if(err) { ready(err,null); // error case asked.forEach(function(fn){ fn(err,null); }); // notify waiters of failure } db = result; // save the reference asked.forEach(function(fn){ fn(db,null); }); // notify all waiters }) } 

这个函数有效地等待第一个提问者的数据库,然后在同一个实例上调用每个人。 请注意,这个函数将使用提供的第一个连接string。

 module.exports = function(db) { return function(req, res, next) { openDb(db,function(err,db){ if(err) handleDbOpenErrorLogicHere(); // middleware stuff, same db available here, call next to continue }); }; }