JavaScript 传递数据时的变量范围问题
JavaScript variable scope issue when passing data
我是 JavaScript 的新手,我一直对我认为是全局变量的范围有疑问。
这是我通过 Socket.IO 从用户那里接收数据的地方:(server.js)
var locationData = {lat: '-20', long: '20'};
var latNumber;
var longNumber;
//SocketIO data
var chat = require('express')();
var http = require('http').Server(chat);
var io = require('socket.io')(http);
io.sockets.on('connection', function (socket) {
socket.on('new message', function (msg) {
locationData = msg;
latNumber = parseFloat(locationData.lat);
longNumber = parseFloat(locationData.long);
io.emit('message', msg.message);
});
});
http.listen(5670, function(){
console.log('listening on *:5670');
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
function getLat(){
return latNumber;
}
function getLong(){
return latNumber;
}
这是我想要接收数据的 HTML 脚本:(HelloWorld.html)
<script type="text/javascript" src="/server.js"></script>
<script>
var viewer = new Cesium.Viewer('cesiumContainer');
var citizensBankPark = viewer.entities.add({
name : 'Test',
position : Cesium.Cartesian3.fromDegrees(getLat(),getLong()),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : 'Test',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
</script>
我正在尝试将 server.js 中定义和设置的 latNumber 和 longNumber 中的数据读取到 HelloWorld.html 中的位置分配中。我遇到的问题是一旦数据到达 HelloWorld.html 它是未定义的,并在浏览器中给出错误。
现在我不确定的是为什么它是未定义的。在 server.js 中记录 latNumber 和 longNumber 变量工作正常并且其中有数据。还将 getLat() getLong() 中的 return 语句更改为硬编码变量(例如 15)也可以正常工作,并将其传递到 HelloWorld.html,然后它会执行它应该执行的操作。只有当我将两者结合在一起时才会出错!
任何帮助或指点将不胜感激!谢谢!
你遇到了各种各样的问题。您的 server.js
文件看起来根本不像客户端代码,它看起来应该是 运行 通过 Node.js 连接服务器。您是否使用 Node.js 到 运行 server.js
来侦听端口 5670,正如此代码所建议的那样?
如果是这样,很好,但是删除客户端代码上的 <script src="/server.js">
引用。您不希望客户端读取服务器的源代码(理想情况下甚至不应该提供它,但那是另一个话题)。
所以现在你有一个新问题:你的服务器有 getLat
和 getLon
功能,在客户端根本不存在。您需要将信息从服务器传输到客户端。
在 server.js 中,您可以添加一些代码以通过 REST 提供这些号码:
chat.get('/location', function(req, res, next) {
var response = {
lat: latNumber,
lon: lonNumber
};
res.type('application/json');
res.send(JSON.stringify(response));
});
此服务器代码将侦听对 URL /location
的请求,并使用包含数字的 JSON 字符串进行响应。
接下来,您的客户端代码应该从服务器异步请求这些值(这意味着我们不会在等待服务器响应时锁定浏览器的 UI)。这是这样做的:
var viewer = new Cesium.Viewer('cesiumContainer');
Cesium.loadJson('/location').then(function(data) {
viewer.entities.add({
name : 'Test',
position : Cesium.Cartesian3.fromDegrees(data.lon, data.lat),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : 'Test',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
});
在上面的代码中,loadJson
returns一个获取数据的promise,我们添加了一个回调函数,在promise resolve时执行。回调接收服务器的数据作为参数,并构建一个新实体。您可以看到实体的位置是基于从服务器接收到的数据。
如果服务器的位置想法发生变化,您可能需要让客户端定期轮询新位置,或者您可以使用多种不同的技术(长轮询、服务器端推送、EventSource, WebSockets, 等) 来让客户端更新。但对于初学者来说,只需重新加载客户端页面即可看到新位置。
我是 JavaScript 的新手,我一直对我认为是全局变量的范围有疑问。
这是我通过 Socket.IO 从用户那里接收数据的地方:(server.js)
var locationData = {lat: '-20', long: '20'};
var latNumber;
var longNumber;
//SocketIO data
var chat = require('express')();
var http = require('http').Server(chat);
var io = require('socket.io')(http);
io.sockets.on('connection', function (socket) {
socket.on('new message', function (msg) {
locationData = msg;
latNumber = parseFloat(locationData.lat);
longNumber = parseFloat(locationData.long);
io.emit('message', msg.message);
});
});
http.listen(5670, function(){
console.log('listening on *:5670');
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
function getLat(){
return latNumber;
}
function getLong(){
return latNumber;
}
这是我想要接收数据的 HTML 脚本:(HelloWorld.html)
<script type="text/javascript" src="/server.js"></script>
<script>
var viewer = new Cesium.Viewer('cesiumContainer');
var citizensBankPark = viewer.entities.add({
name : 'Test',
position : Cesium.Cartesian3.fromDegrees(getLat(),getLong()),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : 'Test',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
</script>
我正在尝试将 server.js 中定义和设置的 latNumber 和 longNumber 中的数据读取到 HelloWorld.html 中的位置分配中。我遇到的问题是一旦数据到达 HelloWorld.html 它是未定义的,并在浏览器中给出错误。
现在我不确定的是为什么它是未定义的。在 server.js 中记录 latNumber 和 longNumber 变量工作正常并且其中有数据。还将 getLat() getLong() 中的 return 语句更改为硬编码变量(例如 15)也可以正常工作,并将其传递到 HelloWorld.html,然后它会执行它应该执行的操作。只有当我将两者结合在一起时才会出错!
任何帮助或指点将不胜感激!谢谢!
你遇到了各种各样的问题。您的 server.js
文件看起来根本不像客户端代码,它看起来应该是 运行 通过 Node.js 连接服务器。您是否使用 Node.js 到 运行 server.js
来侦听端口 5670,正如此代码所建议的那样?
如果是这样,很好,但是删除客户端代码上的 <script src="/server.js">
引用。您不希望客户端读取服务器的源代码(理想情况下甚至不应该提供它,但那是另一个话题)。
所以现在你有一个新问题:你的服务器有 getLat
和 getLon
功能,在客户端根本不存在。您需要将信息从服务器传输到客户端。
在 server.js 中,您可以添加一些代码以通过 REST 提供这些号码:
chat.get('/location', function(req, res, next) {
var response = {
lat: latNumber,
lon: lonNumber
};
res.type('application/json');
res.send(JSON.stringify(response));
});
此服务器代码将侦听对 URL /location
的请求,并使用包含数字的 JSON 字符串进行响应。
接下来,您的客户端代码应该从服务器异步请求这些值(这意味着我们不会在等待服务器响应时锁定浏览器的 UI)。这是这样做的:
var viewer = new Cesium.Viewer('cesiumContainer');
Cesium.loadJson('/location').then(function(data) {
viewer.entities.add({
name : 'Test',
position : Cesium.Cartesian3.fromDegrees(data.lon, data.lat),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : 'Test',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
});
在上面的代码中,loadJson
returns一个获取数据的promise,我们添加了一个回调函数,在promise resolve时执行。回调接收服务器的数据作为参数,并构建一个新实体。您可以看到实体的位置是基于从服务器接收到的数据。
如果服务器的位置想法发生变化,您可能需要让客户端定期轮询新位置,或者您可以使用多种不同的技术(长轮询、服务器端推送、EventSource, WebSockets, 等) 来让客户端更新。但对于初学者来说,只需重新加载客户端页面即可看到新位置。