mongoose中的异步set方法

Asyncronous set method in mongoose

当使用 Mongoose & MongoDB 注册新用户时,我想在保存用户实例之前从另一个集合中获取值。目前我使用以下解决方案,但这会导致用户被保存两次......更糟糕的是,如果用户没有通过第一次验证,无论如何都会调用 set 方法中的 save() ......通常会导致未捕获的异常。

我当前的代码按以下方式工作:

UserSchema.path('address.postCode').set(function(newVal, cb) {
    var that = this;

    this.model('PostCode').findOne({ postCode: newVal }, function(err, postCode) {
        if(postCode) {
            that.longitude = postCode.longitude;
            that.latitude = postCode.latitude;
        } else {
            that.longitude = undefined;
            that.latitude = undefined;
        }
        that.save();
    });
    return newVal;
});

有人知道更好的方法吗?

SchemaType#set 函数需要同步 return。您在此函数中有一个异步调用,因此 return 将在 PostCode return 其结果之前被调用。

此外,您不应该在 setter 中调用 save(),因为它无论如何都会被保存。

既然你想从另一个模型中获取数据,你应该使用一个预中间件。例如:

UserSchema.pre('save', true, function (next, done) {
    var that = this;

    if(this.isNew || this.isModified('address.postCode')) {
        this.model('PostCode').findOne({ postCode: that.address.postCode }, function(err, postCode) {
            if(postCode) {
                that.longitude = postCode.longitude;
                that.latitude = postCode.latitude;
            } else {
                that.longitude = undefined;
                that.latitude = undefined;
            }
            done();
        });
    }

    next();
});

传递给 pre (true) 的第二个参数定义了这是一个异步中间件。

有关中间件的更多信息,请查看 mongoose docs