我有一个把手模板,其中包含两个部分和一个从上下文填充的单个数据。
<h1>Welcome to {{title}}</h1>
<div id="views">
<div id="place">{{> place}}</div>
<div id="player">{{> player}}</div>
</div>
现在,在ExpressJS路线上,我正在执行以下操作:
var express = require('express');
var router = express.Router();
var gameDal = require('../app/DAL/gameRepository');
router.use('/', (req, res, next) => {
if(!res.locals.gameContext) res.locals.gameContext = {};
gameDal.getGame(0).then(game => {
res.locals.gameContext.player = game.player;
res.locals.gameContext.place = game.place;
req.gameTitle = game.title;
next();
});
});
router.get('/', (req, res) => {
res.render('home', { "title": req.gameTitle });
});
module.exports = router;
代码按预期工作,但是,如果我从“then”回调中取出“next()”语句,则两个部分都会正确填充接收到的数据,但“gameTitle”值未定义。
换句话说,以下内容不会替换模板中的{{title}}值,因为在渲染模板时,req.gameTitle值为“undefined”:
router.use('/', (req, res, next) => {
if(!res.locals.gameContext) res.locals.gameContext = {};
gameDal.getGame(0).then(game => {
res.locals.gameContext.player = game.player;
res.locals.gameContext.place = game.place;
req.gameTitle = game.title;
});
next();
});
所以我的问题是:
谢谢。
答案 0 :(得分:1)
next()
允许路由继续。如果允许该路由继续,则在正确填充res.locals
之前,可能会在设置这些值之前进行渲染。那显然是错的。
因此,您只想在中间件中完成工作并且所有内容都设置为呈现(或链中的下一个中间件)时调用next()
。
为什么部分用数据填充,而包含的模板不是?
如果某些事情发生了有效而其他事情没有发生,那么你可能只是陷入了平局的运气中。时间问题。当您不等待调用next()
时,您将在异步操作和渲染中涉及的其他异步操作之间创建竞争。由于这些类型的比赛是不可预测的,它可能会起作用,它可能不起作用,或者它的某些部分可能起作用。使用正确代码的想法是删除所有种族,因此它始终有效。
保持&#34; next()&#34;会有什么影响?承诺回调中的声明?
它所属的位置(在promise回调中),用于正确和可预测的执行。只有当回调执行时,您才真正为渲染的后续步骤准备好所有内容,这样才能调用next()
并继续路由。
如果承诺被拒绝怎么办?
你必须有一个拒绝处理程序,并决定适当的响应是什么。如果将next()
放在它所属的.then()
处理程序中并且您没有拒绝处理程序,那么您的请求将永远不会发送响应,最终浏览器将超时。您需要一个.catch()
处理程序,它可能返回500类型的错误页面。您可以调用next(err)
err
出现某种错误,然后您可以使用一般错误处理中间件来提供错误页面。有关使用Express进行常规错误处理的信息,请参阅此答案:
例如,您可以执行以下操作:
router.use('/', (req, res, next) => {
if(!res.locals.gameContext) res.locals.gameContext = {};
gameDal.getGame(0).then(game => {
res.locals.gameContext.player = game.player;
res.locals.gameContext.place = game.place;
req.gameTitle = game.title;
next();
}).catch(err => {
next(err);
});
});
// Generic error handler for express - should be last middleware defined
// on app object
// Note that this has four arguments compared to regular middleware that
// has three arguments
// This will handle the next(err) call
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
});