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

时间:2014-07-28 18:32:30

标签: node.js express refactoring

我将路线分成不同的模块。但是,仍有相当多的重复。是否有一些关于如何从路径中提取代码的良好实践和约定?

我有很多有效的路线(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和承诺,但是我害怕使用大锤拍打苍蝇。

1 个答案:

答案 0 :(得分:1)

我不确定我是否完全根据您的第一部分问题理解您的问题,您可以通过两种方式实现这一目标。

小清洁方式

将公共逻辑移至router.param

在这种情况下,对于任何请求方法,都会执行

router.param“GET”和“POST” http://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并链接回调。

“/:某事”请求.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');
  });
});