2017-03-03 73 views
0

我有一个句柄模板,其中包含两个部分和一个从上下文中填充的数据。在ExpressJS中使用promise,handlebar和middleware

<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; 

的代码工作正常,但如果我把“下一个()”语句出来的“然后”回调,这两个部分都与收到的数据正确填充,但“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(); 
}); 

所以我问题是:

  1. 怎么会谐音被填入数据和含模板是不是?
  2. 在promise回调中保留“next()”语句会产生什么影响?
  3. 如果承诺被拒绝会怎样?

谢谢。

回答

1

next()允许路由继续。如果您允许该路由在您正确填充res.locals之前继续,那么在设置这些值之前可能会进行渲染。这显然是错误的。

因此,当您的工作在中间件中完成并且所有内容都设置为渲染(或链中的下一个中间件)时,您只需要致电next()

这些部分如何填充数据并且包含的​​模板不是?

如果某些事情发生了,而另一些事情却没有发生,那么您可能会碰到一个“运气不好”的时机问题。当您不等待致电next()时,您正在创建异步操作与渲染中涉及的其他异步操作之间的竞争。由于这些类型的比赛是不可预测的,它可能有用,它可能不会或部分可能起作用。用正确的代码的想法是删除所有的比赛,所以它始终工作。

在promise回调中保留“next()”语句会产生什么影响?

这就是它属于的地方(在promise回调中),以实现正确和可预测的执行。只有当该回调执行时,您才能真正准备好接下来的所有渲染步骤,只有在您拨打next()并继续路由时才能完成。

如果承诺被拒绝,该怎么办?

你必须有一个拒绝处理程序并决定什么是正确的响应。如果您将next()放在.then()处理程序中,并且您没有拒绝处理程序,那么您的请求将永远不会发送响应,并且最终浏览器会超时。您需要一个.catch()处理程序,该处理程序可能会返回500类型的错误页面。你可以打电话next(err),其中err是某种错误,然后你可以有一个通用的错误处理中间件,将提供一个错误页面。看到这个答案,以获取有关快速处理一般的错误信息:

Error Handlers in 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!') 
}); 
+0

@SergioRomero - 这个回答你的问题? – jfriend00