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。
当使用 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。