Google Maps和JavaScript for()循环存在问题

Google Maps和JavaScript for()循环存在问题,javascript,google-maps,google-maps-api-3,google-maps-markers,Javascript,Google Maps,Google Maps Api 3,Google Maps Markers,我有一个网站,用户可以通过进入那里的位置来搜索英国的专业摔跤比赛。该网站使用谷歌地图API和定制API查询数据库,并通过AJAX返回事件 我用于迭代API结果的JavaScript函数如下所示: function setMarkers(map, events) { var geocoder = new google.maps.Geocoder(); for (var i=0; i < events.length; i++) { var wrestling_e

我有一个网站,用户可以通过进入那里的位置来搜索英国的专业摔跤比赛。该网站使用谷歌地图API和定制API查询数据库,并通过AJAX返回事件

我用于迭代API结果的JavaScript函数如下所示:

function setMarkers(map, events) {
    var geocoder = new google.maps.Geocoder();
    for (var i=0; i < events.length; i++) {
        var wrestling_event = events[i];
        console.log(wrestling_event);
        var image_a = '/images/marker.png';
        var image_b = '/images/marker-over.png';
        geocoder.geocode({ address: wrestling_event.venue.post_code }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var marker = new google.maps.Marker({
                    position: results[0].geometry.location,
                    map: map,
                    icon: image_a
                });
                var infowindow = new google.maps.InfoWindow({
                    content: '<p><strong>' + wrestling_event.date + ': ' + wrestling_event.name + '</strong><br />' +
                             wrestling_event.venue.name + ',<br />' +
                             wrestling_event.venue.street_address + ',<br />' +
                             wrestling_event.venue.city + ',<br />' +
                             wrestling_event.venue.post_code + '</p>'
                });
                google.maps.event.addListener(marker, 'mouseover', function() {
                    marker.setIcon(image_b);
                });
                google.maps.event.addListener(marker, 'mouseout', function() {
                    marker.setIcon(image_a);
                });
                google.maps.event.addListener(marker, 'click', function() {
                    infowindow.open(map, marker);
                });
            }
        });
    }
};
函数设置标记(映射、事件){
var geocoder=new google.maps.geocoder();
对于(var i=0;i”+摔跤比赛.date+”:“+摔跤比赛.name+”
”+ 摔跤_event.venture.name+,
+ 摔跤比赛地点街道地址+,
+ 摔跤_event.venture.city+,
+ 摔跤\u event.vention.post\u代码+'

' }); google.maps.event.addListener(标记'mouseover',函数(){ marker.setIcon(图像_b); }); google.maps.event.addListener(标记'mouseout',函数(){ marker.setIcon(图像_a); }); google.maps.event.addListener(标记'click',函数(){ 信息窗口。打开(地图、标记); }); } }); } };
这是根据Google Maps API示例改编的,可在以下位置找到:

我遇到的问题是,如果我从定制API返回了多个结果,我的JavaScript函数会一遍又一遍地打印同一事件,尽管记录了
摔跤事件的结果


地理编码块内的
摔跤\u事件
变量似乎被覆盖(或在
for()
循环的第一次迭代后未被覆盖)。这是有原因的吗?

是的,这是有原因的-在循环中构造的所有回调函数都共享相同的变量

循环中的代码块不会像在Java或C#等语言中那样创建新的作用域。只有函数才能创建新的作用域

您可以编写一个单独的函数来返回处理程序。您可以将“摔跤事件”传递到函数中,它可以返回您得到的回调代码。然后将该返回值作为回调参数传递给“geocode()”例程

这是JavaScript中常见的一个陷阱,应该在每一本关于JavaScript的书的封底上加以描述:-)

见我的答案


简短回答:这是因为对
geocoder
的调用是异步的(比如
setTimeout

所以最好创建一个只创建一个标记和附加的信息窗口的函数,然后在每次传递我的
for()
循环时调用该函数?是的,您也可以这样做。关键是以某种方式复制“摔跤事件”值,每个回调函数都可以私自保留该值。如果您将其传递到一个单独的函数中,并在那里执行“geocode()”调用,那么就可以了。谢谢。我使用匿名函数对其进行排序,并将变量作为该函数的参数传递。事实上,您可以使用单独的函数进行排序,也可以使用“.bind()”进行排序,其方式比键入匿名“lambda”函数更简洁。