在函数范围之外更改变量

时间:2015-04-01 04:13:03

标签: javascript

所以我有当前的代码:

exports.retrieveMessages = function retrieveMessages () {
    var messages = [];
    User_Message.find({}, function(err, msgs) {
        if (err) throw err;
        // object of all the users
        msgs.forEach(function(entry) {
            messages.push({username: entry.username, message: entry.message});
            //console.log(entry.message);
            //console.log(entry.username);
        });
    });
    console.log(messages);
    return messages;
}

在User_messages.find()之后,消息仍然是空的。有没有办法将结果推送到消息变量?我验证了如果我将console.log(消息)移动到foreach循环中,它实际上会打印东西,这意味着我在foreach循环中看到的消息与外部消息不同。

另外,这是因为函数内部的消息是一个局部变量,因此我实际上将它推到另一个变量上?

2 个答案:

答案 0 :(得分:0)

问题似乎是User_Message.find是异步的。直到它返回并调用内部回调messages将这些新值推入其中,这是在外部函数retrieveMessages之后返回。

任何依赖于返回消息的代码都必须通过传递给User_Message.find的回调来调用。

答案 1 :(得分:0)

您的User_Messages.find是异步的。如果它是同步的,你可以做你正在做的事情。但由于它是异步的,你必须这样做。

exports.retrieveMessages = function retrieveMessages (callback) {
    var messages = [];
    User_Message.find({}, function(err, msgs) {
        if (err) {
           callback(err);
        } else {
          // object of all the users
          msgs.forEach(function(entry) {
            messages.push({username: entry.username, message: entry.message});
          });
          callback(null, messages);
        }
    });
}

然后在使用retriveMessages函数时可以执行此操作

retrieveMessages(function(err, messages){
  // handle err
  if(err){
    throw err; //or you can show friendly error message to user and log it.
  }
  //now you can access messages
  console.log(messages);
});

对于那些对js的事件循环和异步性质感到困惑的初学者,我强烈推荐这篇演讲https://www.youtube.com/watch?v=8aGhZQkoFbQ