无法在事件处理程序中更新函数变量,除非它全局声明

时间:2017-11-15 22:29:29

标签: javascript node.js mongoose scope socket.io

我有一个nodejs后端应用程序,它利用mongoose进行数据库连接和查询,在这种情况下,在socket.io的事件处理程序中执行,即 io.on("connection", [callback])

但是,每当我在io.on("connection")的事件处理程序中运行查询时,就像socket.on("myEvent", [callback])一样,我在后一个事件处理程序中更新变量时遇到了麻烦 - 特别是当它是mongoose查询的回调时。

对于某些情境,继承人和我试图运行的例子:

io.on("connection", function(socket) {
  var myVar; // declare user within event handler scope
  socket.on("myEvent", function(m) {
    var query = m.myQuery;
    User.findOne({query}, function(err, doc) {
    if (err) {
      // error handling
    } else {
      myVar = doc;
      console.log(myVar); // logs whole document as it should
    }
  });

  socket.on("myOtherEvent", function(m){
    console.log(myVar); // undefined!?
  });
});

我也尝试在自己的函数上使用自定义回调来解决这个问题,该函数运行相同的查询并返回文档,因为我认为这可能是由于db查询异步引起的 - 但是,这种方法不会工作要么。

此外,我尝试在var that = this方法中使用(显然臭名昭着)socket.on("myEvent)方法,希望它能引用原始回调。那部分也没有运气。

要么我错过了猫鼬的整个观点,要么我会发疯;帮助将不胜感激!

编辑:如前所述,只要我全局声明myVar,变量就会在所述mongoose查询的else块中更新。然后,我可以通过其他socket.on处理程序访问它。

我应该在socket.on("connection")块中声明我的变量,它保持不变,例如如果我在console.log(myVar)内声明myVar = "why isn\'t this working?!"socket.on("myOtherEvent")实际将"why isn't this working?!"记录到控制台

编辑2 :此处描述了一个非常类似的问题:Node, Mongoose - Can't access parent scope in query callback

然而,使用myVar = myVar || {}的解决方案无效。

编辑3 :按照建议,我使用(在本例中为ES6)我的查询的Promises,我更新的查询(仍然在socket.on内,这里没有显示)看起来如下我根据它做的例子:

User.findOne({query}).exec().then(function(doc) {
    if (!doc) {
        myVar = null; // unrelated
        logger.debug("Couldnt find user!"); // unrelated
    } else {
        myVar = doc;
        logger.debug(doc); // correctly prints the whole document
        logger.debug(user); // also correctly prints whole document
    }
}).catch(function(err){
    logger.error("Error searching for query: " + err);// unrelated
});

按照目前的情况,我应该稍后尝试访问myVar(在查询完成并且文档打印到控制台后,在else - 块内)它仍会打印出初始值我给它的价值。无论是null,bool还是字符串 - 它都保持不变。

但是:值得注意的是,如果我全局声明它,它会开始更新变量 - 但是,它对于套接字并不是唯一的,这就是为什么这种方法不能工作的原因针对这个具体问题

1 个答案:

答案 0 :(得分:0)

最初由@Bergi解决 - 谢谢!

对于任何不知道(因为我一直)的新手或人士,无法合并套接字连接:

与此问题特别相关的是Socket.io创建了多个实例/处理程序 - 每个插槽一个,具体而言。 这意味着拥有多个套接字连接将使用所述事件处理程序创建多个实例,这也会导致这些变量的多个实例。

如果您想 - 出于任何原因 - 具有特定于每个套接字连接的本地范围变量,这也非常有用。例如。

谢谢!