Javascript 尝试在没有回调地狱的快速路由中避免匿名函数
我正在尝试使用express和mongodb清理我的节点应用程序,使其更具可读性。我试图避免使用匿名回调函数,并给它们命名,以使其更具可读性 我有一个路由,它进行数据库调用,然后呈现一个页面 原始工作代码Javascript 尝试在没有回调地狱的快速路由中避免匿名函数,javascript,node.js,nodes,Javascript,Node.js,Nodes,我正在尝试使用express和mongodb清理我的节点应用程序,使其更具可读性。我试图避免使用匿名回调函数,并给它们命名,以使其更具可读性 我有一个路由,它进行数据库调用,然后呈现一个页面 原始工作代码 app.get('/updatebeer', function(req, res, next){ var query = {'_id':req.query.id}; Brew.find(query, function(err, result){ if(err)
app.get('/updatebeer', function(req, res, next){
var query = {'_id':req.query.id};
Brew.find(query, function(err, result){
if(err)
return next(err);
if(result.length===1)
res.render('updatebeer', {brew: result[0]});
});
});
我可以为第一次回调使用函数名,而不会出现问题
function updateBeer(req, res, next){
var query = {'_id':req.query.id};
Brew.find(query, function(err, result){
if(err)
return next(err);
if(result.length===1)
res.render('updatebeer', {brew: result[0]});
});
}
app.get('/updatebeer', updateBeer);
但是如果我尝试删除Mongo查询中的匿名函数
function updateBeer(req, res, next){
var query = {'_id':req.query.id};
Brew.find(query, renderBeer);
}
function renderBeer(err, result){
if(err)
return next(err);
if(result.length===1)
res.render('updatebeer', {brew: result[0]});
}
app.get('/updatebeer', updateBeer);
我遇到一个未定义res的错误,我有点理解这个问题,但我不确定修复它的最佳方法?这不会完全解决您的问题,但使用Promise语法可能有助于稍微清理您的函数。使用Mongo节点驱动程序,如果省略回调,Mongo将返回一个承诺,您可以
然后
function updateBeer(req, res, next) {
var query = {
'_id': req.query.id
};
Brew
.find(query)
.then((result) => {
if (result.length === 1)
res.render('updatebeer', {
brew: result[0]
});
})
.catch((err) => {
return next(err);
});
}
app.get('/updatebeer', updateBeer);
下面代码的问题在于,正如node告诉您的那样,res
是在updateber
中定义的,而不是renderBeer
:
function updateBeer(req, res, next){
var query = {'_id':req.query.id};
Brew.find(query, renderBeer);
}
function renderBeer(err, result){
if(err)
return next(err); // There is no "next" in this scope
if(result.length===1)
res.render('updatebeer', {brew: result[0]}); // There is no "res" in this scope either
}
app.get('/updatebeer', updateBeer);
我甚至建议将你的程序分解成一种MVC结构,所有与啤酒相关的东西都归为一个啤酒模型,面向路线的啤酒东西都在你的啤酒控制器中。您已经将啤酒视图的内容划分为啤酒视图,因为您res.render(“updateber”)
简洁啤酒“模型”
啤酒控制器
这是一个不错的方法(考虑到所问的问题,非常好)。也就是说:如果每一位都有一个特定的函数,我发现代码更容易理解。在这里,数据访问和业务逻辑(转换)嵌入到路由处理程序中。我倾向于让路由处理程序负责请求和响应,而不是任何与当前特性相关的逻辑。我怀疑最初的问题没有被问到他们是否在定义的层中工作…@akaphenom同意,路由器应该不知道甚至有一个DB后端。谢谢你的回答。我并不打算给你打电话并给出你的答案,只是想给原始海报提供关于更好的编码风格的见解。stack的一个副作用是,如果代码组织得当,我们通常会给出一些问题的明确答案,而答案几乎鼓励了这种模式。谢谢你的确认!谢谢你的详细回答。我让我的应用程序以一种“黑客”的方式工作,并希望应用一些更好的编码实践,使其更易于维护和可读。我想从命名函数开始,然后研究其他方法,比如承诺,但我认为它们更容易。
function beerTransformer(beerResult) {
if (beerResult.length !== 1) {
throw new Error("THERE'S NO BEER!!!");
}
return Promise.resolve(beerResult[0]);
}
function updateBeer(req, res, next) {
var query = {
'_id': req.query.id
};
Brew
.find(query)
.then(beerTransformer)
.then((beer) => {
// Very thin, delegates all beer related things to the model
return res.render("updatebeer", {
brew: beer
});
})
.catch((err) => {
return next(err);
});
}
app.get('/updatebeer', updateBeer);