代码之家  ›  专栏  ›  技术社区  ›  Matt Bradshaw

尝试在没有回调地狱的快速路由中避免匿名函数

  •  1
  • Matt Bradshaw  · 技术社区  · 7 年前

    我正在尝试使用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);
    

    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 回复  |  直到 7 年前
        1
  •  3
  •   zero298    7 年前

    这并不能完全解决您的问题,但使用Promise语法可能有助于稍微清理您的函数。有了Mongo节点驱动程序,如果省略回调,Mongo会给你一个承诺,你可以这样做 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);
    

    下面代码的问题是,正如node告诉您的那样, 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);
    

    我甚至建议将你的程序分解成一种MVC结构,在这种结构中,所有与啤酒相关的东西都被放在一个啤酒模型中,你的面向路线的啤酒东西都在你的啤酒控制器中。从你开始,你已经有了啤酒视图的内容 res.render("updatebeer")

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