我是Node.js的新手,我将我的一个简单网站迁移到Node.js主要是为了学习体验。
在我的所有网站中,我都希望在网站上保留最相关的信息,并在#34; 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 :(得分: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的实际实现取决于您选择的存储。这里使用promises而不是经典回调的好处是,如果你有多个中间件在到达最终处理函数之前加载不同的数据元素,它们将并行执行而不是顺序执行。您可能希望使用Promise.all()等待最终函数中所需的所有承诺。