2013-12-20 44 views
0

我試圖通過將Express/Kraken.js控制器分解爲更小的回調函數來避免回調地獄。如何在express/node控制器中查看數據範圍

我正在處理一個請求,並有大約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 = {};但對我來說,控制器包含任何'全局狀態'..最好的辦法是什麼來處理呢?

回答

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); 
}; 
+0

真棒謝謝你。非常明確的答案。 – bonez

+0

供參考。我將「全局變量」附加到res.locals中。 res.locals.products根據http://expressjs.com/api.html#res.locals – bonez

+0

如果您打算在視圖中使用它也是一個好方法 – vkurchatkin

相關問題