我有一个User
对象,在其构造函数中创建一个mongoose数据库对象。
mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/Data');
var db = mongoose.connection;
UserSchema = new mongoose.Schema({
username: String,
salt: String,
hash: String,
});
UserDB = mongoose.model('users', UserSchema);
function User(id) {
var self = this;
if (id)
UserDB.findById(id, function(err, user) { // async
if (!err && user)
self.db = user;
});
}
但是当我创建用户对象时,由于它是异步数据库调用,因此不会立即创建UserDB
。
user = new User('53179fd401d540b8c5000001');
if (user.db)
console.log('fail '+user.db.id); // fails because !user.db yet
else
setTimeout(function() {
if (user.db)
console.log('pass '+user.db.id); // only now it works
}, 1000);
我能做什么,除非创建了DB对象,否则构造函数不会返回,或者其他什么东西不能让我做不可靠的setTimeout?
答案 0 :(得分:0)
有许多可能性可以阻止这种情况。
事实是,您的数据库会像您正确说的那样实例化异步。
V1:您可以将回调传递给用户构造函数参数。
function User(id, ready) {
var self = this;
if (id)
UserDB.findById(id, function(err, user) { // async
if (!err && user)
self.db = user;
if(ready !== undefined)
ready.call(this);
});
}
new User(1, function() {
console.log(this); // <- your users instance
});
V2:否则你需要一个用户(生产者消费者模式)的事件队列,在所有实例化后都会被调度。
V3:使用JQuery事件,然后调用$ .when方法收集多个回调。
v4:编写自己的回调队列以同步回调。
答案 1 :(得分:0)
想象我使用了承诺
var when = require('when');
function User(id) {
var d = when.defer();
this.ready = d.promise;
var self = this;
if (id)
UserDB.findById(id, function(err, user) { // async
if (!err && user){
self.db = user;
d.resolve();
} }); }
user = new User('53179fd401d540b8c5000001');
user.ready.then(function(){
console.log(user.db.id);
});