地理编码后,变量值在循环内未更改

时间:2019-01-17 14:31:10

标签: javascript

以下代码循环遍历一个包含2个值的JSON数组-city_name和counter,并在地图上放置一个图钉。

我正在尝试在Google地图的信息弹出窗口上显示city_name和counter,但是在第一个循环之后变量不会更改。

例如JSON中的最后一项是Blackpool,但在所有循环中,它始终为Blackpool,并且始终为Blackpool。

function initMap() {
        var resultsNonJSON = document.getElementsByName('tbResults')[0].value;
        var jsonResults = JSON.parse(resultsNonJSON);
        var geocoder = new google.maps.Geocoder();
        var myLatLng = {lat: 53.810066, lng: -1.776427};
        var votes;
        var town;

        var map = new google.maps.Map(document.getElementById('dvMap'), {
            center: {lat: 54.636633, lng: -2.952166},
            zoom: 6
        });

        for(var i = 0; i  < jsonResults.length; i++) {
            var obj = jsonResults[i];
            town = obj.city_name;

            geocoder.geocode({'address': obj.city_name.concat(", UK")}, function(results, status) { 
                if (status == 'OK') 
                {
                    var contentString = '<div id="content">'+
                        '<div id="siteNotice"></div>'+
                        '<h1 id="firstHeading" class="firstHeading">' + town + '</h1>'+
                        '<div id="bodyContent">'+
                        '</div>'+
                        '</div>';

                    var infowindow = new google.maps.InfoWindow({
                      content: contentString
                    });

                    var marker = new google.maps.Marker({
                        position: results[0].geometry.location,
                        map: map,
                        title: obj.city_name,
                        icon: {
                            url: "https://maps.google.com/mapfiles/ms/icons/green-dot.png"
                        }
                    });
                    marker.addListener('click', function() {
                        infowindow.open(map, marker);
                    });
                }
                else 
                {
                  alert('Geocode was not successful for the following reason: ' + status);
                }
            });
        }                   
    }

有什么想法为什么会这样?同样,如果我要显示i值,它将始终为7。似乎在调用地址解析后停止更改变量。

1 个答案:

答案 0 :(得分:0)

您正在数组循环内调用异步代码。就您而言,

地理代码是一个异步函数,由于多种原因,您在回调函数中获得的结果可能会延迟,并且这也是不可预测的。

有多种解决方案可以解决此问题。

  1. 解决此问题的一种方法是,如果使用ES6,则在for循环中使用let范围变量而不是var。请参见下面的示例。

 

   let list = ['Canada', 'US', 'Japan', 'Mexico'];

for (let i = 0; i < list.length; i++) {
  geoCode(list[i], function(index) {
    createMarker(list[i]); // test the value (let vs var)
  });
}

function geoCode(item, cb) {
  setTimeout(function() {
    cb(item);
  }, 4000);

}

function createMarker(i) {
  console.log(i);

}

就您而言,只需更改

for(var i = 0; i  < jsonResults.length; i++)

for(let i = 0; i  < jsonResults.length; i++) 

并在循环内移动 town 变量

 for (let i = 0; i < jsonResults.length; i++) {
                var obj = jsonResults[i];

                geocoder.geocode({ 'address': obj.city_name.concat(", UK") }, function (results, status) {
                    if (status == 'OK') {
                        town = jsonResults[i].city_name;
  1. 下一个解决方案是在循环内部使用闭包。我们需要使用匿名IIFE包装您的异步函数。

        (function (town) {
    
            geocoder.geocode({ 'address': obj.city_name.concat(", UK") }, function (results, status) {
                if (status == 'OK') {
                    var contentString = '<div id="content">' +
                        '<div id="siteNotice"></div>' +
                        '<h1 id="firstHeading" class="firstHeading">' + town + '</h1>' +
                        '<div id="bodyContent">' +
                        '</div>' +
                        '</div>';
    
                    var infowindow = new google.maps.InfoWindow({
                        content: contentString
                    });
    
                    var marker = new google.maps.Marker({
                        position: results[0].geometry.location,
                        map: map,
                        title: obj.city_name,
                        icon: {
                            url: "https://maps.google.com/mapfiles/ms/icons/green-dot.png"
                        }
                    });
                    marker.addListener('click', function () {
                        infowindow.open(map, marker);
                    });
                }
                else {
                    alert('Geocode was not successful for the following reason: ' + status);
                }
            });
    
        })(town);