我试图通过将我的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 = {};
,但对我来说,控制器包含任何“全局状态”......最好的方法是什么?
答案 0 :(得分:3)
这样做是个坏主意。它将导致竞争条件类型问题 - 基本上它与在多线程环境中共享数据相同。相反,您可以使用req
或res
来存储数据。要做到这一点,你需要在范围内,所以你可以在路由处理程序中定义所有函数或使每个函数成为中间件,因此它将req
和res
作为参数。以下是此方法的示例:
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);
};