【问题标题】:How to return documents by mongoose find?如何通过 mongoose find 返回文件?
【发布时间】:2017-04-10 21:42:13
【问题描述】:

在我的应用程序中,我像这样使用带有蓝鸟的猫鼬:

var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

在同一个文件中,我拥有一个在数据库中搜索“约会”-documents 的函数。该函数的返回应该是找到的文档的结果数组,而不是承诺、查询或其他东西。

但不幸的是,程序似乎会在承诺实现之前跳回调用函数。那我该如何处理呢?

这是我当前状态下的函数:

get_intersecting_appointment: function(appointment) {

        var appointmentQuery = AppointmentModel.find({
            $and: [{
                    begin: {
                        $lte: appointment.begin
                    }
                },
                {
                    end: {
                        $gte: appointment.end
                    }
                }
            ]
        });

        return appointmentQuery.then(function(appointments) {
            debug("Found appointments:");
            debug(appointments);

            if (appointments) {
                return appointments;
            } else {
                return [];
            }

        });


    },

提示:调用函数在内部debug("Found appointments:") 之前打印“下一个调试输出”;从上面。可以说,调用函数如下所示:

appointment_is_available: function(appointment) {

        var appointments = dbcon.get_intersecting_appointment(appointment);
        //...
}

【问题讨论】:

    标签: node.js mongodb mongoose bluebird


    【解决方案1】:

    根据Node.js性质,您可以使用回调来解决此类问题

    使用callback

    根据您的代码,我尝试添加回调

    get_intersecting_appointment: function(appointment,callback) {
    
        var appointmentQuery = AppointmentModel.find({
            $and: [{
                begin: {
                    $lte: appointment.begin
                }
            }, {
                end: {
                    $gte: appointment.end
                }
            }]
        });
    
        return appointmentQuery.then(function(appointments) {
            debug("Found appointments:");
            debug(appointments);
    
            if (appointments) {
                callback(null,appointments);
            } else {
                callback(null,[]);
            }
    
        });
    
    },
    

    //调用时添加回调函数

    appointment_is_available: function(appointment) {
    
            var appointments = dbcon.get_intersecting_appointment(appointment,function(err,result){
                if(!err){
                    consoole.log(result)
                }
            });
            //...
    }
    

    更新

    您也可以使用Promiseasync module

    【讨论】:

    • 好吧,即使这可以正常工作,我更愿意取消异步代码,因为调用函数将被另一个函数调用,我只是想避免构建一长串通过的函数回调。此外,我还必须处理 appointment_is_available 函数中的结果,因为我只想从中返回一个布尔值。如果我只得到一个回调,该函数将在回调被调用之前返回,所以这里也有同样的问题(没有办法等待像“than”或恕我直言的回调)。
    • 好吧,所以你可以使用Promiseasync module
    • 是的,这就是起源问题:我上面的示例使用带有 then 方法的 promise,但它不会等待 then(...) 的结果,然后返回调用函数,即不是我预期的行为。那我怎么能在这里等待承诺的兑现呢?
    • 根据您的代码,您的外部函数不是承诺,这就是外部将要执行的原因。你也可以承诺
    • 好吧,我不会在调用函数中处理任何承诺,而只是在get_intersecting_appointment 函数中解决所有承诺或查询,因此我将在appointment_is_available 中获得真实的文档。调用函数不应处理任何承诺行为,而应仅处理具体数据。
    【解决方案2】:
    var appointmentQuery = AppointmentModel.find({
                $and: [{
                        begin: {
                            $lte: appointment.begin
                        }
                    },
                    {
                        end: {
                            $gte: appointment.end
                        }
                    }
                ]
            });
    

    将上面的代码替换为下面的代码

    var appointmentQuery = AppointmentModel.find({
                $and: [{
                        begin: {
                            $lte: appointment.begin
                        }
                    },
                    {
                        end: {
                            $gte: appointment.end
                        }
                    }
                ]
            }).exec();
    

    注意- 在每次 mongoose 操作后使用 .exec() 以保证使用它是一个很好的做法。因为.exec() 返回一个未决的承诺。

    现在来到你使用这个功能的地方就像var appointments = dbcon.get_intersecting_appointment(appointment);。请参阅此处dbcon.get_intersecting_appointment(appointment) 这将返回一个您分配给变量的承诺,并且它是异步的,因此在此完成之前正在执行下一行。还有一件事,从.then() 返回的值只能在另一个链接的.then 中访问。您不能简单地将 .then() 返回的值分配给全局变量。您必须链接另一个 then 才能利用该值。您需要在调用dbcon.get_intersecting_appointment(appointment) 的位置稍作修改。你需要这样做

    dbcon.get_intersecting_appointment(appointment).then(function(res){
        //res is either empty array or the result array
        //rest of your code here
    
    })
    

    【讨论】:

    • 我也尝试过这种方法,但它导致的行为与我的问题中的版本相同。这很奇怪,因为 exec() 确实返回了一个承诺,但 return appointmentQuery.then(...) 行仍然不会等待 then 的结果,并且会立即跳回来。 :(
    猜你喜欢
    • 2019-03-19
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 2020-09-12
    • 2011-09-05
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多