猫鼬pre.save()异步中间件无法按预期工作 [英] Mongoose pre.save() async middleware not working as expected

查看:56
本文介绍了猫鼬pre.save()异步中间件无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自:猫鼬唯一验证错误类型

我将此模式与npm中的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 index,并且仅在此之后调用console.warn().

在根据文档调用了所有中间件done()之前,不应调用save操作,我应该找回验证错误.

done()行为似乎未按预期运行,

知道为什么吗?

解决方案

您正在使用并行中间件回调函数(同时具有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();
        }
    });
});

Following up from : Mongoose unique validation error type

I'm using this schema with mongoose 3.0.3 from npm:

var schema = new Schema({

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

});

With this middleware to get a validationError from unique:true

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();
});

However, it does not work!

Users.create() will still return a a MongoError: E11000 duplicate key error index and the console.warn() is only called after that.

The save action should not be called until all middleware done()have been called according to the docs, and I should get back a validation error.

It looks like the done() behavior is not working as expected,

Any idea why?

解决方案

You're using a parallel middleware callback function (with both next and done), but you're not setting the parallel flag in the schema.pre parameters so it's using the serial rules.

So either include the parallel flag in your call:

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

Or switch to a serial middleware callback style if that's all you need anyway:

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();
        }
    });
});

这篇关于猫鼬pre.save()异步中间件无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆