2

对不起,如果这听起来很傻,我还在学习服务器端 Javascript。我的 app.js 文件中有这段代码。

var test;

UserModel.findOne({name: 'guest'}, function(err, user) {
    test = user.name;
});

console.log(test);

我知道这不起作用,因为UserModel.findOne它是异步的,所以一切都必须在回调中发生。例如console.log(test)可以在完成之前执行UserModel.findOne

问题

如果我var test在 app.js 文件中声明,有没有办法将user.name(via UserModel.findOne) 的值放入其中?

我这样做的原因是因为我希望提前从数据库中检索所有这些信息。这样我就不必每次需要用户名时都进行数据库查询。

如果这个想法不合理,是否有类似的替代方案?

编辑/更新

这不用于身份验证/登录。我打算让所有用户都可以访问该变量test及其内容。

本质上,我在问为什么变量没有test永久设置为user.name,而是只在回调范围内执行。而且,是否可以永久设置变量?

4

4 回答 4

2

这个例子:

var users = {};
function getUser(username, callback) {
    if (typeof users[username] !== 'undefined') {
        callback(users[username]);
    } else {
        Users.findOne({"name":username}, function(err, user) {
            users[username] = user;
            callback(user);
        });
    };
};

这将始终从缓存或 mongodb 返回命名用户。它的调用方式与 findOne 相同:

getUser('guest', function(user) { console.log(user); });

之后,您可以直接从缓存中访问用户或将其分配给变量。但是你必须先确保 getUser 已经成功。

Node.js 最难的事情之一是理解代码是在书面源代码的正常流程之外调用的。代码仅跟随对具有回调的函数的调用是不够的。

于 2012-09-22T18:09:03.347 回答
1

考虑到您的应用程序的所有用户都会共享该test变量,这似乎是个坏主意。如果您不想根据需要进行查找,您可以将这种数据存储在用户会话中。

编辑

只要您test在全局或模块范围内声明,它就会在findOne回调中永久设置。

于 2012-09-22T15:50:03.410 回答
0

是的,您可以将结果应用于更高范围的变量,例如这应该有效;

var test;

function getTest() {
   console.log(test);
}

UserModel.findOne({name: 'guest'}, function(err, user) {
   test = user.name;

   getTest();
});
于 2012-09-22T15:53:21.933 回答
0

看看下面六氰化物的答案。在异步回调中使用回调为我的项目节省了同样的问题。

将变量设置为 Mongoose Find 的结果

于 2015-05-10T21:41:38.413 回答