函数外部的未定义变量

时间:2017-02-22 05:05:10

标签: node.js socket.io p5.js

我有一个使用node.js和socket.io的代码。

当我以这种方式编写此代码时;

服务器端:

var position;
var resolution = {
		width: 1366,
		height: 666
	};

	socket.emit('display', resolution);

	socket.on('positioning',
		function(data){
			position = data;
		});
	console.log(position); // <---

客户方;

var position;
var resolution = {
		width: 1366,
		height: 666
	};

	socket.emit('display', resolution);

	socket.on('positioning',
		function(data){
			position = data;
      console.log(position); // <---
		});
	

位置变量未定义,但如果我在客户端使用此代码

{{1}}

它有价值。为什么我不能在函数外部使用socket.io发送的值?

5 个答案:

答案 0 :(得分:1)

在第一个客户端方案中,您的console.log(position)在您的事件处理程序运行之前运行。请记住,当您执行socket.on(...)时,您只是注册一个可能在将来某个时间调用的事件处理程序。其余代码继续运行。因此,注册事件处理程序后的下一行是console.log()语句。由于事件处理程序尚未被触发(它已注册,但尚未发生任何事件使其运行),position尚无值。

所以,看看你的代码:

socket.on('positioning', function(data) {
    position = data;
});
// position has not yet been set because the above event handler
// has not yet been triggered
console.log(position);

使用positioning事件发送的数据的唯一安全的地方是在回调中,这正是您在其他方案中正常工作所做的事情:

socket.on('positioning', function(data) {
    // use the data here
    console.log(data);
});

仅供参考,这是事件驱动编程的基本概念。您注册将来某个时间调用的事件处理程序。您通常不知道何时会调用它们,因此您必须在调用事件处理程序时处理它们在事件处理程序中提供的数据。

答案 1 :(得分:1)

仔细考虑这行代码的作用:

socket.on('positioning',
   function(data){
      position = data;
   });

这是设置一个回调函数,当你收到positioning事件时会调用它。但请注意,此功能尚未调用!它将在未来的某个时间召唤。这只是函数的初始化

如果您在回调函数初始化之后<{1}}调用 ,那么console.log()将在之前发生实际调用该函数!这就是变量未定义的原因,因为该变量尚未设置!

如果您将console.log()调用调用回调函数,那么您可以保证在调用回调函数后发生,因此变量已经确定了。

如果不使用内联函数,可能会更清楚:

console.log()

这正是你的代码正在做的事情,除了现在我使用的是命名函数而不是内联函数。但现在更明显的是,在执行var position; var resolution = { width: 1366, height: 666 }; socket.emit('display', resolution); socket.on('positioning', myCallback); console.log(position); function myCallback(data){ position = data; } 时尚未调用回调。

答案 2 :(得分:0)

socket.on()是一个异步调用 - 这意味着只有在 data从服务器上完全加载后才会调用匿名函数

注意:在运行匿名函数后,您可以使用 匿名函数之外的其他代码中的position(是的,您需要等待访问它)。但是怎么样?好吧,最好的方法是将依赖代码放入自己的函数中,然后在回调函数中调用该函数,如下例所示:

var position;
var resolution = {
  width: 1366,
  height: 666
};

socket.emit('display', resolution);

socket.on('positioning',
  function(data) {
    loadPosition(); // <---
  }
);

function loadPosition() {
  position = data;
  console.log(position); // ... do whatever you need to do with postion here
}

答案 3 :(得分:0)

您可以传递从callBack响应中收到的对象/值

var position;
var resolution = {
    width: 1366,
    height: 666
};

socket.emit('display', resolution);

socket.on('positioning',
    function(data){
        position = data;
    positionUpdate()
    });

function positionUpdate(){
console.log(position); 
}

答案 4 :(得分:0)

如果您尚未解决问题,请尝试此操作。这就是我所做的。

var resolution = {
    width: 1366,
    height: 666
};

socket.emit('display', resolution);

socket.on('positioning', function(data){
    getPosition(data, position);
});

var getPosition = function(data, callback){
   callback(data);
}

var position = function(data){
   console.log(data); // <--
}