2014-10-01 3 views
3

У меня относительно простой проект с очень маленьким кодом, который дает мне головные боли, поскольку я не знаю, что вызывает проблему. Идея похожа на http://tweetping.net/, но она не показывает твиты в реальном времени, а в режиме реального времени соединения пользователей с сервисом.JavaScript, объекты и параллелизм

Служба использует nodejs как прослушиватель UPD и socket.io для связи с веб-браузером. Затем Socket.io прислушивается к сообщениям, и когда он получает один, он рисует маркер на карте Google.

Это весь 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> 

Проблема происходит, когда есть много одновременных сообщений (100/с), поступающих от Socket.io. Маркеры создаются просто отлично с помощью метода createMarker, но когда я попытаюсь удалить их через 3 секунды (через setTimeout), объект markers[name] не определен.

Я бы сделал пример fiddle.js, но невозможно воссоздать многие параллельные сообщения socket.io.

У кого-нибудь была ситуация, когда javascript не смог нажать что-то объекту через синтаксис object[key] = something;? Любые другие идеи?

ОБНОВЛЕНИЕ: Примечание для себя: всегда проверяйте, есть ли у вас этот ключ в объекте маркеров. Добавление следующего кода помогло решить проблему.

if (name in markers) { 
    return; 
} 
+3

Вы получаете одно и то же имя дважды? – Neo

+0

это не исправить вашу проблему, но вы должны использовать 'setTimeout (destroyMarker.bind (это, имя), 3000);' Я также задаюсь вопросом, работает ли функция setMap асинхронно, а удаление выполняется до завершения этой функции? просто мысль. – bencripps

+1

Хорошие люди! Я не думал, что дважды получаю makrer с тем же именем, но на самом деле добавляю 'if (name in markers) {return; } 'решил проблему. – markz

ответ

1

Возможно, вы получили одно и то же имя дважды (или больше) за 3 секунды.

  1. маркеры [имя] установлено из первого сообщения
  2. маркеров [имя] перезаписываются из второго сообщения
  3. маркеров [имя] удаляются (после того, как таймер из первого сообщения)
  4. Таймера от второго сообщения , но маркеры [имя] уже удалены.
Смежные вопросы