Nodejs函数在内部函数完成之前返回

Nodejs function returns before internal function completes

本文关键字:返回 函数 内部函数 Nodejs      更新时间:2023-09-26

我试图返回MongoDB中是否已经存在用户。在collection.find()内运行console.log会打印正确的数量(大于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;
}

正如一些人所指出的,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

我接受了提示,最终重新构造了代码。我创建了一个函数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)
        }
    });
}

因为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
              })