简体   繁体   English

JavaScript,对象和并发

[英]JavaScript, objects and concurrency

I have a relatively simple project with very little code that is giving me headaches as I don't know what is causing the problem. 我有一个相对简单的项目,代码非常少,令我头疼,因为我不知道是什么导致了这个问题。 The idea is similar to http://tweetping.net/ , but it is not showing real-time tweets, but real-time connections of users to a service. 这个想法类似于http://tweetping.net/ ,但它没有显示实时推文,而是显示用户与服务的实时连接。

The service uses nodejs as a UPD listener and socket.io to communicate with the web browser. 该服务使用nodejs作为UPD侦听器和socket.io与Web浏览器进行通信。 Socket.io then listens to messages and when it receives one it draws a marker on a Google map. 然后Socket.io会收听消息,当收到消息时,它会在Google地图上绘制一个标记。

This is the entire JavaScript on the page: 这是页面上的整个JavaScript:

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
    var socket = io();
    var map = false;
    var markers = {};
    var markerTimeouts = {};

    $(window).load(function() {
        var mapOptions = {
            zoom: 3,
            center: new google.maps.LatLng(30, 16),
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            panControl: false,
            streetViewControl: false,
            zoomControlOptions: {
                style: google.maps.ZoomControlStyle.LARGE,
                position: google.maps.ControlPosition.TOP_RIGHT
            },              
        };
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    });

    function createMarker(name, lng, lat) {
        var circle = new google.maps.Marker({
                position: new google.maps.LatLng(lat, lng),
                map: map,
                icon: "/img/marker_red.png?v=2",
                title: name
        });

        markers[name] = circle;

        setTimeout(function() { destroyMarker(name); }, 3000);
    }

    function destroyMarker(name) {
        markers[name].setMap(null);
        delete markers[name];
    }

    socket.on('message', function(data){
        if (!map) {
            return;
        }
        else {
            createMarker(data.name, data.lon, data.lat);
        }
    });
    </script>

The problem happens when there are a lot of concurrent messages (100/s) coming from socket.io. 当有很多来自socket.io的并发消息(100 / s)时,就会出现问题。 The markers get created just fine via the createMarker method, but when I try removing them 3 seconds later (via setTimeout) the object markers[name] is undefined. 通过createMarker方法可以很好地创建标记,但是当我尝试在3秒后删除它们时(通过setTimeout),对象markers[name]是未定义的。

I would make a fiddle.js example, but it's impossible to recreate the many concurrent socket.io messages. 我会做一个fiddle.js示例,但是重新创建许多并发的socket.io消息是不可能的。

Did anybody have a situation where javascript was not able to push something to an object via the object[key] = something; 有没有人有javascript无法通过object[key] = something;推送某个对象的情况object[key] = something; syntax? 句法? Any other ideas? 还有其他想法吗?

UPDATE : Note to self: always check if you already have this key in the markers object. 更新 :自我注意:始终检查您是否已在markers对象中拥有此键。 Adding the following code solved the issue. 添加以下代码解决了这个问题。

if (name in markers) {
    return;
}

You are probably getting the same name twice (or more) in 3 seconds. 您可能在3秒内获得相同的名称两次(或更多)。

  1. markers[name] is set from first message markers [name]是从第一条消息设置的
  2. markers[name] is overwritten from second message 标记[名称]被第二条消息覆盖
  3. markers[name] is deleted (after timer from first message) 标记[名称]被删除(从第一条消息开始计时)
  4. Timer from second message is over but markers[name] is already deleted. 第二条消息的计时器结束但标记[名称]已被删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM