如何在express / node控制器中调整数据范围

时间:2013-12-20 18:40:58

标签: javascript node.js express callback

我试图通过将我的Express / Kraken.js控制器分解为更小的回调函数来避免回调地狱。

我正在处理一个请求,并且有大约6个级别的嵌套匿名回调函数。

所以现在我的主要功能看起来像这样:

// ugh, I know this isn't right
var globalProducts = {};

module.exports = function (server) {

    server.get('/project', function (req, res) {
        var data = req.query;
        globalData = data; 

        if(!data.projectId || !data.ruleSetId) 
            res.json({error: "Incomplete input data."});

             // pass response to products call back 
        Project.findOne({ _id: mongoose.Types.ObjectId(data.projectId) }, setUpProducts);   
    });
};

function setUpProducts(err, project){
    // get all products and pass them down the pipe
    project.findAllChildren(setUpRules);
}

function setUpRules(err, products) {
    // we need to access products in another function 
    globalProducts = products; 
    // find the rule set and build the rule Flow
    RuleSet.findOne({ _id: mongoose.Types.ObjectId(globalData.ruleSetId) }, function(err, ruleSet) { 
        ruleSet.buildFlow(processFlow);
    });
}

我的问题是在回调之间传递信息的最佳方法是什么?我的解决方案是var globalProducts = {};,但对我来说,控制器包含任何“全局状态”......最好的方法是什么?

1 个答案:

答案 0 :(得分:3)

这样做是个坏主意。它将导致竞争条件类型问题 - 基本上它与在多线程环境中共享数据相同。相反,您可以使用reqres来存储数据。要做到这一点,你需要在范围内,所以你可以在路由处理程序中定义所有函数或使每个函数成为中间件,因此它将reqres作为参数。以下是此方法的示例:

function check (req, res, next) {
  if(!req.query.projectId || !req.query.ruleSetId) return res.json({error: "Incomplete input data."});  
  next()
}

function findProject (req, res, next) {
  Project.findOne({ _id: mongoose.Types.ObjectId(req.query.projectId) }, after);  

  function after (err, project) {
    if (err) return next(err);
    req.project = project;
    next();
  }
}

function findProducts (req, res, next) {
   req.project.findAllChildren(after)

  function after (err, products) {
    if (err) return next(err);
    req.products = products;
    next();
  }
}

function respond (req, res) {
  res.render('view', {
    products : req.products,
    project : req.project
  });
}


module.exports = function (server) {
   server.get('/project', check, findProject, findProducts, respond);
};