我正在尝试返回用户是否已存在于MongoDB中。在console.log
内运行collection.find()
会打印正确的数量(大于0)。但是,当调用userExists
时,它始终返回false
(0)。
如何在返回值之前让Javascript等待这些函数完成?我读过关于jQuery的$.Deffered()
,但这对我来说很脏,而且没用。
function userExists(db, uid){
var collection = db.get('users');
var ret = 0;
collection.find({"uid":uid},{},function(e,docs){
ret = docs.length
});
return ret > 0?true:false;
}
答案 0 :(得分:1)
有些人已经注意到,collection.find
是异步的,所以当你到达userExists
中的下一行(你已经获得return ret > 0?true:false;
的那一行)时,它太早了,价值太高了ret
尚未确定。在collection.find
(以及它依次调用的任何函数)的回调之外的任何地方,查询还没有发生。
在查询之后(基本上)没有办法“暂停”userExists
,因此您需要更改整个方法。你需要的是延续模式。这意味着无论你对collection.find
的结果做什么都必须在回调中发生。
我不知道您要对ret
做什么,所以这可能意味着您的代码组织方式会发生重大变化。这是一个大纲,我希望能给你一般的想法:
function processResultAndDisplayToTheUser(ret) {
//everything that needs to happen after the value of ret is set
if (ret > 0) {
doSomething();
} else {
doSomethingElse();
}
}
function userExists(db, uid){
var collection = db.get('users');
//ret doesn't exist here
collection.find({"uid":uid}, {}, function(e,docs){
var ret = docs.length;
//ret finally exists, so pass it to a function and use it
processResultAndDisplayToTheUser(ret);
});
//ret doesn't exist here either
}
//ret still doesn't exist here
答案 1 :(得分:1)
我接受了提示并最终重组了我的代码。我创建了一个函数addUpdateUser(),在那里进行了计数,然后相应地运行了addUser()或updateUser()函数。
addUpdateUser(db, {
"uid" : uid,
});
function addUpdateUser(db, userInfo){
var collection = db.get('users');
collection.find({"uid":userInfo.uid},{},function(e,docs){
if(docs.length > 0){
updateUser(db, userInfo)
}else{
addUser(db, userInfo)
}
});
}
答案 2 :(得分:0)
因为collection.find是不会立即返回的异步方法,所以需要将代码更改为,
你可以传递一个回调函数
function userExists(db, uid,callback){
var collection = db.get('users');
collection.find({"uid":uid},{},function(e,docs){
callback(docs.length);
});
}
现在您可以将此userExists函数称为
userExists(db, uid,function(ret){
//do something here
})