У меня относительно простой проект с очень маленьким кодом, который дает мне головные боли, поскольку я не знаю, что вызывает проблему. Идея похожа на 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;
}
Вы получаете одно и то же имя дважды? – Neo
это не исправить вашу проблему, но вы должны использовать 'setTimeout (destroyMarker.bind (это, имя), 3000);' Я также задаюсь вопросом, работает ли функция setMap асинхронно, а удаление выполняется до завершения этой функции? просто мысль. – bencripps
Хорошие люди! Я не думал, что дважды получаю makrer с тем же именем, но на самом деле добавляю 'if (name in markers) {return; } 'решил проблему. – markz