2014-07-19 38 views
0

我是Node.js的新手,我正在將一個簡單的站點遷移到Node.js,主要是作爲一種學習體驗。Node.js中間件是不是

在我所有的網站中,我喜歡在「sitemeta」對象中保留網站上最相關的信息。這是從Redis每個請求中查詢的,如果失敗的話(它只會在sitemeta得到更新後纔會執行,然後從MySQL讀取它並將其保存在redis中,以便下次請求再次從redis獲取它,因爲redis比MySQL快得多)。

因此,在PHP中,我只需在settings.php文件中添加sitemeta的調用,我總是將其包含在每個文件的頂部,這樣像home_url或site_mode(sitemeta對象的一部分)的信息始終存在。

但是,現在在Node.js中,我想知道是否真的是要走的路,或者是否有更好的方法在每個控制器文件的頂部實際發生這種情況而不是像中間件那樣發生路由器文件,真的)。

//in index.js 

var express = require('express'); 
var router = express.Router(); 
var site = require('./../lib/sitemeta'); 

... 
//using it for something. 
var siteMeta = site.meta(); 
res.render('index', { title: siteMeta.title }); 

或者,可我甚至在app.js實例化的sitemeta所以,它的查詢只有一次(當節點app.js開始),除非它需要更新,如果是刷新可不知何故惹?

謝謝。

+0

這可能是一個很好的例子,你可以使用['app.locals'](http://expressjs.com/4x/api.html#app.locals)。 –

+0

所以基本上,你是說從app.js中調用它,然後通過app.locals傳遞它,對嗎? – Adergaard

回答

1

我認爲最好的方法是通過一箇中間件。無論你在哪裏存儲元數據(內存,redis等),擁有中間件都會讓你在所有請求中注入siteMeta,並根據接收到的請求(區域設置等)調整siteMeta。我們通常使用很多小的,易於測試的中間件函數來爲流水線中的另一箇中間件注入不同的數據元素來處理和產生響應。

// with promises 
app.use(function(req, res, next){ 
    req.siteMeta = loadSiteMeta(); 
    next(); 
}); 

app.get('/endpoint', function(req, res){ 
    // wait for the promise to be fulfilled 
    req.siteMeta.then(function(siteMeta){ 
     res.render('my-view', { title: siteMeta.title }); 
    }); 

}); 

// without promises 
app.use(function(req, res, next){ 
    loadSiteMeta(function(err, siteMeta){ 
     req.siteMeta = siteMeta; 
     next(); 
    }); 
}); 

app.get('/endpoint', function(req, res) { 
    // siteMeta will be populated 
    res.render('my-view', { title: req.siteMeta.title }); 
}); 

loadSiteMeta的實際實現將取決於您選擇的存儲。這裏使用Promise而不是經典回調的好處是,如果您有多箇中間件在到達最終處理函數之前加載不同的數據元素,它們將並行執行而不是按順序執行。您可能希望使用Promise.all()等待最終函數中需要的所有承諾。