Mongoose pre.save()异步中间件无法按预期工作

时间:2012-11-27 11:08:29

标签: node.js validation mongodb mongoose

跟进:Mongoose unique validation error type

我在npm:{/ p>中使用此模式与mongoose 3.0.3

var schema = new Schema({

    _id: Schema.ObjectId,
    email: {type: String, required: true, unique: true}

});

使用此中间件从unique:true

获取validationError
schema.pre("save", function(next, done) {
    var self = this;

    model.findOne({email : this.email}, 'email', function(err, results) {
        if(err) {
            done(err);
        } else if(results) {
            console.warn('results', results);
            self.invalidate("email", "email must be unique");
            done(new Error("email must be unique"));
        } else {
            done();
        }
    });

    next();
});

然而,它不起作用!

Users.create()仍会返回MongoError: E11000 duplicate key error indexconsole.warn()仅在此之后调用。

在根据文档调用所有中间件done()之前,不应调用保存操作,我应该返回验证错误。

看起来done()行为没有按预期工作,

知道为什么吗?

1 个答案:

答案 0 :(得分:39)

您正在使用并行中间件回调函数(包含nextdone),但您没有在schema.pre参数中设置并行标志,因此它使用的是串行规则。

所以要么在你的电话中加入并行标志:

schema.pre("save", true, function(next, done) { ...

或者切换到串行中间件回调样式,如果这就是你所需要的:

schema.pre("save", function(next) {
    var self = this;

    model.findOne({email : this.email}, 'email', function(err, results) {
        if(err) {
            next(err);
        } else if(results) {
            console.warn('results', results);
            self.invalidate("email", "email must be unique");
            next(new Error("email must be unique"));
        } else {
            next();
        }
    });
});