mongoose中的异步设置方法

时间:2015-03-16 19:21:34

标签: node.js mongodb 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;
});

任何人都知道更好的方法吗?

1 个答案:

答案 0 :(得分:0)

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

另外,你不应该在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();
});

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

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