首页 > 解决方案 > 由 ajax 响应覆盖的变量

问题描述

使用谷歌地图和地理编码器,我试图循环一个地址对象,为它们返回 LatLng 地址,并在setMarker下面的函数中使用原始详细信息和 latlng 地址创建标记。

问题是,response[a]被对象中的最后一个地址覆盖,因为 for 循环在 AJAX 结果返回之前运行。

如何保存当前response[a]循环中的数据,以便setMarker()以后调用时,它包含正确的信息?

谢谢

          var limit = 0;

          for (a in response){

            if(limit<5){ // limit API calls

                  var addr = [response[a].Addr1, response[a].City, response[a].Zip];

                  geo = new google.maps.Geocoder();
                  geo.geocode({
                    address: addr.join(", "),
                    componentRestrictions: {
                    //  country: 'UK'
                    }
                  }, function (results, status) {

                    if (status == google.maps.GeocoderStatus.OK && results) {

                        var latitude = results[0].geometry.location.lat();
                        var longitude = results[0].geometry.location.lng();
                        var latlng = new google.maps.LatLng(latitude, longitude);

                        if(latitude!="" && longitude!=""){

                            bounds.extend(latlng);
                            map.fitBounds(bounds);
                            _this.setMarker(map, limit, latlng, response[a]);

                        }

                    } // if geo results

              });

            }

            limit++;

          }

标签: javascriptgoogle-mapsgoogle-geocoder

解决方案


您面临的问题是一个可以使用闭包函数解决的经典问题。

当前代码看起来像:

var a[20];

for(i=0;i<20;i++) {
    some_async_method() {
        //code that uses 'a[i]'
    }
}

使用闭包在异步函数中保留 var a 的范围:

var a[20];

for(i=0;i<20;i++) {
    (function(_a){
        some_async_method() {
            //code that uses 'a[i]' as '_a'
        }   
    })(a[i]);// self calling function that preserves the scope of a[i]
}

所以你的代码看起来像:

var limit = 0;

for (a in response){

if(limit<5){ // limit API calls

      var addr = [response[a].Addr1, response[a].City, response[a].Zip];

      geo = new google.maps.Geocoder();
      (function(response_a){ // closure function to preserve scope of 'response[a]' 
          geo.geocode({
            address: addr.join(", "),
            componentRestrictions: {
            //  country: 'UK'
            }
          }, function (results, status) {

            if (status == google.maps.GeocoderStatus.OK && results) {

                var latitude = results[0].geometry.location.lat();
                var longitude = results[0].geometry.location.lng();
                var latlng = new google.maps.LatLng(latitude, longitude);

                if(latitude!="" && longitude!=""){

                    bounds.extend(latlng);
                    map.fitBounds(bounds);
                    _this.setMarker(map, limit, latlng, response_a);

                }

            } // if geo results

      });
    })(response[a]);

}

limit++;

}

推荐阅读