如何保存从mongoose中的query.exec()函数返回的对象

时间:2015-10-20 18:47:20

标签: node.js mongodb mongoose

我是猫鼬新手。 这是我的情景:

var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
children: [childSchema]});
var Parent = mongoose.model('Parent', parentSchema);

假设我已经创建了一个包含子项的父级'p',我正在使用

查询'p'
var query = Parent.find({"_id":"562676a04787a98217d1c81e"});
query.select('children');                                   
query.exec(function(err,person){                            
    if(err){                                                    
        return console.error(err);                               
    } else {                                                     
        console.log(person);                                     
    }
});                                                    

我需要访问异步函数之外的person对象。关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:5)

Mongoose的 find() 方法是 asynchronous ,这意味着你应该使用一个回调来包装来自< strong> find() 方法。例如,在您的情况下,您可以将回调定义为

function getChildrenQuery(parentId, callback){
    Parent.find({"_id": parentId}, "children", function(err, docs){
        if (err) {
          callback(err, null);
        } else {
          callback(null, docs);
        }
    }); 
}

然后您可以这样调用:

var id = "562676a04787a98217d1c81e";
getChildrenQuery(id, function(err, children) {
    if (err) console.log(err);

    // do something with children
    children.forEach(function(child){
      console.log(child.name);
    });
});

您可以采取的另一种方法是 exec() 方法返回 Promise 的承诺,以便您可以执行以下操作: / p>

function getChildrenPromise(parentId){
   var promise = Parent.find({_id: parentId}).select("children").exec();
   return promise;
}

然后,当您想获取数据时,您应该将其设为异步:

var promise = getChildrenPromise("562676a04787a98217d1c81e");
promise.then(function(children){
    children.forEach(function(child){
        console.log(child.name);
    });
}).error(function(error){
    console.log(error);
});

答案 1 :(得分:0)

你无法在回调之外访问它(=&#34; async函数&#34;你提到过)。这就是node.js的工作原理:

  • 你对数据库的调用需要一些时间 - 比较它只需要执行一个简单的代码语句很长一段时间。
  • Node.js是非阻塞的,所以它不会等待数据库返回结果,并且会在query.exec语句之后执行代码而立即继续。
  • 所以在query.exec语句之后编写的代码在数据库返回结果之前运行,因此无法在那里使用该结果。

但是......拥抱异步编程:

  • 只需将所需的所有代码写入&#34; async函数&#34;
  • 将回调传递给您的函数,从&#34;异步函数&#34;中调用它。并传递查询结果