试图避免在没有回调地狱的快速路线中的匿名功能

时间:2017-10-02 15:54:57

标签: 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) 
            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的错误,我有点理解这个问题,但我不确定修复它的最佳方法?

1 个答案:

答案 0 :(得分:3)

这不能完全解决您的问题,但使用Promise语法可能有助于稍微清理您的功能。使用Mongo节点驱动程序,如果省略回调,Mongo会给你一个Promise,你可以then

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);

您对以下代码的问题是,正如节点告诉您的那样,res定义了updateBeer,而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);

res.render("updatebeer")

我甚至建议将你的程序分解为一种MVC结构,其中所有与啤酒相关的东西都被降级为啤酒模型,而你的路线导向啤酒的东西都在啤酒控制器中。自function beerTransformer(beerResult) { if (beerResult.length !== 1) { throw new Error("THERE'S NO BEER!!!"); } return Promise.resolve(beerResult[0]); } 以来,您已经将Beer View的内容划分为啤酒视图。

Terse Beer“Model”

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);

啤酒控制器

 $queryPR = "SELECT * FROM `raport` WHERE DATE(`timestamp`) = CURDATE() AND (lokacioni = 'PR')";