在Express中重构类似的路由,提取回调到单独的模块中



我已经把我的路由分成了不同的模块。然而,仍然有相当数量的重复。关于如何从路由中提取代码,是否有一些良好的实践和惯例正在形成?

我有很多这样的路线(Express 4.x):

router.get('/:something', function(req, res, next) {
  manipulate(something);
  Model.findOne( ..., function (err, model) {
    doSomethingInterestingWith(model, function(err, model) {
      res.render('template', { something: model} );
    });
  });
});
router.post('/:something', function(req, res, next) {
  manipulate(something);
  Model.new( {...}).save( function(err, model) {
    res.redirect('/:something');
  });
});

这是在一个文件中,例如,称为routes/something.js

我正在想办法将每条路由的核心提取到一个函数中,这个函数可以提取到一个单独的文件中。我试图尽可能地简化示例,以保持可读性,但实际上,在调用渲染之前有相当多的代码。嵌套回调使我提取的函数非常难看。我想过用Q和promises,但是我害怕用大锤打苍蝇。

根据你问题的第一部分,我不确定我完全理解了你的问题,你可以通过两种方式实现这一点。

Little Cleaner way

移动公共逻辑到router。参数

路由器。param将对任何请求方法执行一次在本例中是get和POSThttp://expressjs.com/4x/api.html router.param

router.param('name', function(req, res, next) {
    manipulate(something);
    //set return value if needed
    //req.something = manipulate(something);
    next();
});
router.get('/:something', function(req, res) {
  //access returned value if needed
  //var modifiedSomething = req.params.something;
  Model.findOne( ..., function (err, model) {
    doSomethingInterestingWith(model, function(err, model) {
      res.render('template', { something: model} );
    });
  });
});
router.post('/:something', function(req, res) {
  //access returned value if needed
  //var modifiedSomething = req.params.something;
  Model.new( {...}).save( function(err, model) {
    res.redirect('/:something');
  });
});

更干净的方式

使用。all并链接回调。

"/:something" request .all()回调将总是运行一次,然后根据请求方法"GET"或"POST"执行相应的回调。

http://expressjs.com/4x/api.html router.route

router.route('/:something')
.all(function (request, response, next) {
    manipulate(something);
    next();
})
.get(function(req, res) {
  Model.findOne( ..., function (err, model) {
    doSomethingInterestingWith(model, function(err, model) {
      res.render('template', { something: model} );
    });
  });
})
.post(function(req, res) {
  Model.new( {...}).save( function(err, model) {
    res.redirect('/:something');
  });
});

最新更新