2012-09-07 38 views
0

我想在预保存回调中增加一个计数器。 我发现这个计算器这样做真正有用的: Does Mongoose support the Mongodb `findAndModify` method?预保存钩子:猫鼬回调的顺序如何

我想作的就是用findAndModify方法。但是当我实现静态时,我的回调序列并不像预期的那样。我经常保存,然后执行findAndModify,但是我希望在pre save钩子的开始和结束之间执行findAndModify。如果我使用回调来定义常规方法,则按预期工作。

与预先保存钩的进行参数还工作没有任何不同的结果

我怎么在这里

我的代码看起来像这样错过:

var mongoose = require('mongoose'); 
var should = require('should'); 

mongoose.connect("localhost","test_db"); 

var CommentSchema = new mongoose.Schema({ 
    content: {type:String}, 
    created_at: {type:Date, default:Date.now}, 
    _post:{type:mongoose.Schema.ObjectId,ref:'Post'} 

}); 

var PostSchema = new mongoose.Schema({ 
    title: {type:String}, 
    content: {type:String}, 
    comments: [{type:mongoose.Schema.ObjectId, ref:'Comment'}], 
    counter: {type:Number} 

    }); 

PostSchema.statics.findAndModify= function(query,sort,doc,options,callback){ 
    return this.collection.findAndModify(query,sort,doc,options,callback); 
} 

PostSchema.statics.test_me = function(clb){ 
    console.log("test_me"); 
    clb(); 
} 
CommentSchema.pre('save',function(next,done){ 
    console.log("enter pre save comment"); 
    if(this.isNew){ 
    Post.findAndModify({_id:this._post},[],{$inc:{count:1}},{new:true},function(err,post){ 
    console.log("enter find-and-modify!"); 
    console.log(post); 
    }); 
    Post.test_me(function(){ 
    console.log("callback of test_me"); 
    }); 
    console.log("exit pre save comment"); 

    next(); 
    } 
}); 

var Post = mongoose.model('Post',PostSchema); 
var Comment = mongoose.model('Comment',CommentSchema); 

var post = new Post({title:"hello world"}); 
var comment = new Comment({content:"1st comment",_post:post}); 
post.comments.push(comment); 

    var id = post.id; 
    console.log(id); 
    post.save(function(err){ 
    comment.save(function(err){ 
     Post.find({_id:id }) 
      .populate('comments') 
      .exec(function(err,result){ 
      console.log("--------------- result -----------------"); 
      console.log(result); 
      }); 
    }); 
    }); 

这是结果从我的命令行:

5049f0d2e21547430a000001 
enter pre save comment 
test_me 
callback of test_me 
exit pre save comment 
enter find-and-modify! 
{ __v: 0, 
    _id: 5049f0d2e21547430a000001, 
    comments: [ 5049f0d2e21547430a000002 ], 
    count: 1, 
    title: 'hello world' } 
--------------- result ----------------- 
[ { __v: 0, 
    _id: 5049f0d2e21547430a000001, 
    count: 1, 
    title: 'hello world', 
    comments: 
    [ { content: '1st comment', 
     _post: 5049f0d2e21547430a000001, 
     _id: 5049f0d2e21547430a000002, 
     __v: 0, 
     created_at: Fri Sep 07 2012 15:04:18 GMT+0200 (CEST) } ] } ] 

编辑:我不想知道如何用test_me按顺序执行findAndModify。我想知道为什么findAndMody在预存完成后进入。即使它是嵌入式的,应该像test_me方法一样工作。所以test_me方法应该说明一个异步方法应该可以嵌套...但findAndModify不会......就像我的命令行输出显示的那样...它在预保存退出后总是进入findAndModify,即使我使用done()回调...

回答

0

因为我们面对的是异步,它将运行

console.log("enter pre save comment"); 
if(this.isNew){ 
    Post.findAndModify({_id:this._post},[],{$inc:{count:1}},{new:true},function(err,post){ 
    console.log("enter find-and-modify!"); 
    console.log(post); 
    }); 
    Post.test_me(function(){ 
    console.log("callback of test_me"); 
    }); 
    console.log("exit pre save comment"); 
    next(); 
} 

一个接一个,而不是等待它来执行或移动到下一个前的响应。由于Post.findAndModify()需要更长的时间才能执行,因此回调函数中的任何内容都将在回调函数之外的任何内容之后执行。

如果你想它,以便您的回复执行更

console.log("enter pre save comment"); 
if(this.isNew){ 
    Post.findAndModify({_id:this._post},[],{$inc:{count:1}},{new:true},function(err,post){ 
    console.log("enter find-and-modify!"); 
    console.log(post); 
    Post.test_me(function(){ 
     console.log("callback of test_me"); 
     console.log("exit pre save comment"); 
     next(); 
    }); 
    });  
} 
+0

感谢...是的,我知道的原因,但它有道理,但我怎么能避免呢?即使我在pre save hook中传递完成的回调函数,它也不起作用 – silverfighter

+0

如果您希望它按顺序执行,请使用async.js获取系列或嵌套您的回调。 –

+0

对于误解我很抱歉,我编辑了这个问题以便更有意义..我想知道findAndModify是如何在预存保存退出时总是进入的... – silverfighter