传递数据时JavaScript变量范围问题

时间:2015-10-28 14:38:10

标签: variables scope socket.io cesium

我对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>

我试图将latNumber和longNumber中的数据读入并在server.js中设置为HelloWorld.html中的位置赋值。我遇到的问题是,一旦数据到达HelloWorld.html,它就是未定义的,并在浏览器中出错。

现在我不确定的是为什么它未定义。在server.js中记录latNumber和longNumber变量可以正常工作并在其中包含数据。将getLat()getLong()中的return语句更改为硬编码变量(如15)也可以正常工作,然后将其传递给HelloWorld.html,然后执行它应该执行的操作。当我将两者结合在一起时,它只会出错!

任何帮助或指示将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:1)

你在这里遇到了很多问题。您的server.js文件根本不像客户端代码,看起来它应该通过Node.js运行服务器。您是否正在使用Node.js运行server.js来侦听端口5670,正如此代码所示?

如果是这样,那么好,但要删除客户端代码上的<script src="/server.js">引用。您不希望客户端阅读服务器的源代码(理想情况下,它甚至不应该提供服务,但这是一个不同的主题)。

现在您遇到了一个新问题:您的服务器具有getLatgetLon功能,客户端上根本不存在这些功能。您需要将信息从服务器传输到客户端。

在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返回一个获取数据的promise,我们添加一个回调函数,以便在promise解析时执行。回调接收服务器的数据作为参数,并构建新的实体。您可以看到实体的位置基于从服务器收到的数据。

如果服务器对位置的想法发生了变化,您可能需要让客户端定期轮询新位置,或者您可以使用多种不同的技术(长轮询,服务器端推送,{ {3}},EventSource等)让客户端更新。但对于初学者,只需重新加载客户端页面即可查看新位置。