重构mongoose查询

时间:2014-07-02 04:09:47

标签: node.js mongoose

我一直在使用猫鼬一个考虑量,我似乎无法绕过"回调地狱"并通过错误处理来污染我的查询。

例如,这是我的路线:

var homePage = function(req, res) {
        var companyUrl = buildingId = req.params.company

        db.pmModel
            .findOne({ companyUrl: companyUrl })
            .exec(function (err, doc) {
                if (err)
                     return HandleError(req, res, err)

                if( !doc )
                    return NoResult(req, res, {msg: 'Aint there'})

                console.log(doc)

                db.rentalModel
                    .find({ propertyManager: doc.id })
                    .populate('building')
                    .exec(function (err, rentals) {
                        if (err)
                             return HandleError(req, res, err)

                        if( !doc )
                            return NoResult(req, res, {msg: 'Aint there'})

                        console.log(doc)

                        var data = doc.toJSON()

                        data.rentals = rentals

                        res.render('homePage', data)
                    })
            })
    } 

我的问题:有没有更简洁的方式来写这个?

1 个答案:

答案 0 :(得分:0)

所以也许你上面的内容只是一个小例子,但在我看来你的代码中没有太多的“回调地狱”(在我看来)。但是,您当然可以重构代码。只要知道这样做,就可以使维护更加难以理解或遵循。

您可以做的一件事就是重构您的数据库层。如果您总是发现自己查询一个集合,然后右转并查询另一个集合,您可以考虑合并这些集合,或者至少是您正在寻找的文档。在关系数据库中,您可以将这些表分开并进行合并,但是在基于文档的数据库中,有时在每个文档中组合数据更有意义。这样可以在代码中实现更简单的查询和更简单的逻辑。

另一个解决方案是将您的调用重构为单独的函数,并以不同的方式控制流。一个受欢迎的库是async,它提供了许多辅助函数来协助JavaScript的异步世界。有很多可供选择,但有一个建议是根据您的情况使用waterfall函数(因为每次调用必须在下一次之前进行)。它看起来像这样:

async.waterfall([
    function(callback){
        findCompany(companyUrl, callback);
    },
    function(id, callback){
        findPropertyManager(id, callback);
    }
], function (err, rentals) {
   res.render(rentals)
});

您仍然需要处理每个函数中的错误,但您甚至可以将其重构为辅助函数。此外,您可以选择自己编写代码以帮助控制流而不是使用异步。

但同样,上面显示的代码是可理解和可读的,并且只包含几个内联回调。通过这种方式,可以进行更少的操作,并且可以使以后调试(如果出现问题)变得更容易。