node.js Mongoose pre.save() 异步中间件未按预期工作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13582862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:43:26  来源:igfitidea点击:

Mongoose pre.save() async middleware not working as expected

node.jsvalidationmongodbmongoose

提问by Olivier

Following up from : Mongoose unique validation error type

跟进:猫鼬唯一验证错误类型

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

我正在使用mongoose 3.0.3来自 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

使用此中间件从 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 indexand the console.warn()is only called after that.

Users.create()仍将返回 aaMongoError: E11000 duplicate key error index并且console.warn()仅在此之后调用。

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.

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

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

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

Any idea why?

知道为什么吗?

回答by JohnnyHK

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

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

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