除非全局声明,否则不能从事件处理函数中的函数更新variables

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

然而,每当我在一个事件处理程序的io.on("connection") ,如socket.on("myEvent", [callback])运行一个查询时更新后处理程序中的variables – 特别是当它mongoose查询的callback。

在某些情况下,inheritance人和我试图运行的例子:

 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!? }); }); 

我也试着用一个自定义的callback函数来处理这个问题,这个函数运行相同的查询并返回文档,因为我认为这可能是由db查询asynchronous造成的,但是这种方法也不能工作。

另外,我试过在socket.on("myEvent)方法中使用(显然是臭名昭着的) var that = this方法,希望能引用原来的callbacksocket.on("myEvent)

要么我错过了mongoose的整个点,要么我要疯了; 帮助将不胜感激!

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

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

编辑2 :这里描述了一个非常类似的问题: Node,Mongoose – 无法在查询callback中访问父级作用域

使用myVar = myVar || {}的解决scheme 然而myVar = myVar || {}确实不起作用。

编辑3 :build议,我使用(在这种情况下,ES6)承诺为我的查询,我更新的查询(仍然在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 block内),它仍然会打印出我给它的初始值。 无论是一个布尔还是一个string – 它保持不变。

但是 ,有趣的是,我应该全局声明它,它开始更新variables – 然而,它不是唯一的套接字,这就是为什么这种方法不适用于这个具体问题

最初由@Bergi解决 – 谢谢!

对于任何不了解的新手或者不熟悉的人(就像我一样),无法合并套接字连接:

与此问题具体相关的是,Socket.io创build多个实例/处理程序 – 每个套接字一个,具体的。 这意味着有多个套接字连接将使用所述事件处理程序创build多个实例,这也会导致这些variables的多个实例。

例如,如果你想出于某种原因,也可以使用特定于每个套接字连接的本地作用域variables,这也是非常有用的。

谢谢!