Javascript没有为变量赋值新值

时间:2015-10-09 11:12:25

标签: javascript mongodb

好的我在node.js文件中这样做。我有一个函数,假设根据某些字段在mongodb中搜索用户。假设捕获其帐户值,然后将其传递以进行进一步评估。但是,帐户变量保持为空。它看起来像这样:

function checkIfUserExist (name, lobby, socket) {
    var account_ID = null;
    Clients.findOne({ user_name_perm: name }, function (err, result) {
        if (err) {
            console.log("Cannot find user with perm name: checkIfUserNameExist");
        } else {
            if (result == null) {
                ...} else {
                console.log("User perm name is: " + result.user_name_perm);
                console.log("result.account_ID: " + result.account_ID);
                account_ID = result.account_ID;
            }
        }
    });
    console.log("Account ID: " + account_ID);


    if (!account_ID == null) {...} else {
        console.log("User doesn't exist");
    }               
}

日志部分如下所示:

Account ID: null
User doesn't exist
User perm name is: Peter
result.account_ID: 15555555555

这对我来说非常混乱,似乎函数正在评估所有内容,但数据库首先查找,这使得account_ID为评估目的为null,然后它进入数据库并在事后进行新的评估,也许,为什么要这样做?!

2 个答案:

答案 0 :(得分:2)

findOne以异步方式运行,因此如果要使用其结果,则必须使用同步机制,例如传递continuation或使用回调。

继续传递

function checkIfUserExist (name, lobby, socket, callback) {
    var account_ID = null;
    Clients.findOne({ user_name_perm: name }, function (err, result) {
        // snip
        console.log("Account ID:", account_ID);

        if (!account_ID == null) {
            callback(null, result);
        } else {
            console.log("User doesn't exist");
            callback(new Error);
        }  
    });                 
}

然后你必须使用一个新参数调用checkIfUserExist - 一个在查询完成时调用并且你知道结果的函数。

承诺

您正在使用的mongo客户端也可能从异步方法返回promise。

function checkIfUserExist (name, lobby, socket) {
    var account_ID = null;
    return Clients.findOne({ user_name_perm: name })
      .then(function (result) {
          console.log("Account ID:", result.account_ID);
          return result;
      }).catch(function (err) {
          // handle error
      });
}

现在,您可以将.then链接到checkIfUserExist的返回值。您仍然必须将回调传递给.then方法。可能看起来像:

checkIfUserExist(name, lobby, socket).then(function (result) {
    response.status(200).json(result);
}).catch(function (err) {
    response.status(500).end(err.message);
});

答案 1 :(得分:0)

这是由于异步

function checkIfUserExist (name, lobby, socket) {
    var account_ID = null;
    Clients.findOne({ user_name_perm: name }, function (err, result) {
        if (err) {
            console.log("Cannot find user with perm name: checkIfUserNameExist");
        } else {
            if (result == null) {
                ...} else {
                console.log("User perm name is: " + result.user_name_perm);
                console.log("result.account_ID: " + result.account_ID);
                account_ID = result.account_ID;
                console.log("Account ID: " + account_ID);

            }
        }
    });


    if (!account_ID == null) {...} else {
        console.log("User doesn't exist");
    }               
}

发生的事情是findOne中的回调比console.log更晚执行...你必须一直处理异步,我建议https://github.com/caolan/async