函数外的未定义变量
Undefined variable outside of a function
我有一个使用 node.js 和 socket.io 的代码。
当我这样写这段代码时;
服务器端:
function display(width, height){
this.width = width * 2;
this.height = height * 2;
}
function position(x, y){
this.x = x;
this.y = y;
}
function initialize(){
for(var x = circlePosition.length; x < circleCount; x++){
circlePosition[x] = new position(Math.random() * (resolution.width - (-resolution.width)) + (-resolution.width), Math.random() * (resolution.height - (-resolution.height)) + (-resolution.height));
}
}
socket.on('display',
function(data) {
resolution = new display(data.width, data.height);
initialize();
io.sockets.emit('positioning', circlePosition);
});
客户端;
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); // <---
});
它有价值。为什么我不能在函数外使用使用 socket.io 发送的值?
在第一个客户端场景中,您的 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);
});
仅供参考,这是事件驱动编程的基本概念。您注册在将来某个时间调用的事件处理程序。您通常不知道它们何时会被调用,因此您必须只处理它们在被调用时在事件处理程序中提供的数据。
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
}
你可以通过你object/value收到的回调响应
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);
}
想想这行代码到底在做什么:
socket.on('positioning',
function(data){
position = data;
});
这是在设置一个 回调函数,当您收到 positioning
事件时将调用该回调函数。但是请注意,这个函数还没有被调用!它将在将来的某个时候被调用。这只是函数的初始化。
如果你在回调函数初始化之后调用,那console.log()
会在[=35之前] =] 该函数实际上被调用了!这就是变量未定义的原因,因为变量还没有被设置!
如果您将 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;
}
这正是您的代码所做的,只是现在我使用的是命名函数而不是内联函数。但是现在更明显的是console.log()
执行的时候回调还没有被调用。
如果您还没有解决问题,请试试这个。这就是我所做的。
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); // <--
}
我有一个使用 node.js 和 socket.io 的代码。
当我这样写这段代码时;
服务器端:
function display(width, height){
this.width = width * 2;
this.height = height * 2;
}
function position(x, y){
this.x = x;
this.y = y;
}
function initialize(){
for(var x = circlePosition.length; x < circleCount; x++){
circlePosition[x] = new position(Math.random() * (resolution.width - (-resolution.width)) + (-resolution.width), Math.random() * (resolution.height - (-resolution.height)) + (-resolution.height));
}
}
socket.on('display',
function(data) {
resolution = new display(data.width, data.height);
initialize();
io.sockets.emit('positioning', circlePosition);
});
客户端;
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); // <---
});
它有价值。为什么我不能在函数外使用使用 socket.io 发送的值?
在第一个客户端场景中,您的 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);
});
仅供参考,这是事件驱动编程的基本概念。您注册在将来某个时间调用的事件处理程序。您通常不知道它们何时会被调用,因此您必须只处理它们在被调用时在事件处理程序中提供的数据。
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
}
你可以通过你object/value收到的回调响应
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);
}
想想这行代码到底在做什么:
socket.on('positioning',
function(data){
position = data;
});
这是在设置一个 回调函数,当您收到 positioning
事件时将调用该回调函数。但是请注意,这个函数还没有被调用!它将在将来的某个时候被调用。这只是函数的初始化。
如果你在回调函数初始化之后调用,那console.log()
会在[=35之前] =] 该函数实际上被调用了!这就是变量未定义的原因,因为变量还没有被设置!
如果您将 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;
}
这正是您的代码所做的,只是现在我使用的是命名函数而不是内联函数。但是现在更明显的是console.log()
执行的时候回调还没有被调用。
如果您还没有解决问题,请试试这个。这就是我所做的。
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); // <--
}