「しかし、関数が終了したらそれをログに記録すると、...」
これにより、あなたはこのようなことをしていると思います...
var user = new User
user.populate();
console.log(user);
その場合、非同期コールバックが呼び出されるconsole.log
ずっと前に が実行されます。.findOne()
への応答に依存するコードはfindOne
、コールバック内で呼び出す必要があります。
編集:あなたの更新は上記の例とは少し異なりますが、理由は同じです。
メソッドにコールバックを渡す理由は、非同期アクティビティfindOne
を実行するためです。そうでない場合、コールバックの理由はありません。の呼び出しの直後に内部コードを配置するだけです。findOne
console.log()
ただし、非同期であるため、後続のコードは実行を待機しません。そのため、コンソールにデータが取り込まれていないオブジェクトが表示されます。
それぞれにラベルを追加するconsole.log()
と、順不同で実行されることがわかります。
var that = this;
db.collection("Users").findOne({email : that.email}, function(err, doc){
if(!err) {
that.firstName = doc.firstName;
that.lastName = doc.lastName;
that.password = doc.password;
}
console.log("inside the callback", that); // this happens Last!!!
});
console.log("outside the callback", that); // this happens First!!!
したがって、呼び出しの順序を観察するconsole.log
と、空の呼び出しがコールバック内の呼び出しの前に発生していることが明らかになります。
編集:.populate()
コールバック内で呼び出されるコールバックをメソッドに受信させることもでき.findOne
ます。
User.prototype.createNickName = function () {
this.nickname = this.firstName.slice(0,3) + '_' + this.lastName.slice(0,3);
};
// >>>------------------------------v----receive a function argument...
User.prototype.populate = function(callback_func) {
var that = this;
db.collection("Users").findOne({email : that.email}, function(err, doc){
if(!err) {
that.firstName = doc.firstName;
that.lastName = doc.lastName;
that.password = doc.password;
}
// all users will have the "createNickName()" method invoked
that.createNickName();
// ...and invoke it in the callback.
callback_func.call(that);
// By using .call(), I'm setting the "this" value
// of callback_func to whatever is passed as the first argument
});
};
// this user wants to log the firstName property in all caps
var user1 = new User;
user1.populate(function() {
console.log(this.firstName.toUpperCase());
});
// this user wants to log the the whole name
var user2 = new User;
user2.populate(function() {
console.log(this.firstName + ' ' + this.lastName);
});
// this user wants to verify that the password is sufficiently secure
var user3 = new User;
user3.populate(function() {
console.log(verify_password(this.password));
});