2014-05-25 23 views
1

我正在寫一些需要訪問數據庫的快遞中間件。它將作爲一個包發佈,所以我希望它儘可能地包含自我。我想知道如何處理與數據庫的連接。它是異步的(當然),但只需在包初始化時發生一次。這發生在哪裏?快速中間件與異步初始化

我在想這樣的事情。問題在於,中間件在數據庫準備就緒之前立即傳回。

// App 
app.use(myMiddleware({ 
    db: "<db connection string>" 
}); 

// Middleware 
module.exports = function(db) { 
    // Open db 

    return function(req, res, next) { 
     // Middleware stuff 
    } 
} 
+0

看看傳遞'next',看看[這個問題和答案](http://stackoverflow.com/q/8710669/1348195)如何。 –

+0

將它傳遞到哪裏? – giodamelio

+0

在完成連接到數據庫之後,調用'.next'來表示完成。 –

回答

1

我建議不要這樣的單例,依賴注入是一個更好的解決方案,每個應用程序的連接幾乎不可擴展。連接池可能是一個更好的主意。

這就是說,你可以這樣做:

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 
    }) 
} 

此功能有效地等待第一個提問者分貝然後調用同一個實例大家。請注意,該函數將使用提供的第一個連接字符串。

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 
     }); 
    }; 
} 
+0

謝謝,那正是我需要的。你說得對,它似乎不是最好的解決方案。我將不得不考慮一下我的架構。 – giodamelio