Google 地图异步添加标记

Google Maps Asynchronously Add Markers

我正在玩 Google 地图 API 并想加载地图,然后使用边界点击外部 API 以获得某个数字的当前天气状况地图中的城市。我 运行 遇到的问题是,如果我有 async: false 它工作正常,但是一旦我设置 async: true 标记就不再加载。这就是我所拥有的,我觉得它真的很简单。

function initialize()
{
  var mapProp = {
    center: new google.maps.LatLng(41.8369,-95.6847),
    zoom:4,
    disableDefaultUI:true,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };
  map = new google.maps.Map(document.getElementById("googleMap"),mapProp);

  google.maps.event.addListener(map, 'bounds_changed', function() {
      calcBounds();
  });

function calcBounds() {
  var bounds = map.getBounds();
  var ne = bounds.getNorthEast();
  var sw = bounds.getSouthWest();
  for (var lat = ne.lat(); lat > sw.lat(); lat = lat - 5) {
    for (var long = ne.lng(); long > sw.lng(); long = long - 5) {
      $.ajax({
        async: false,
        url: 'http://api.openweathermap.org/data/2.5/weather?lat=' + lat + '&lon=' + long + '&APPID=' + apikey,
        dataType: "json",
        success: function(data) {
          var marker = new google.maps.Marker({
            map: map,
            position: new google.maps.LatLng(lat, long),
          });//End Marker
        },//End Success
        error: function() {
         alert("ERROR");
        }
      });//End AJAX
    }//End Long for
  }//End lat For
}//End function

您遇到的问题是学习者的常见问题Javascript。正在发生的事情是,每次您进行一次循环迭代时,纬度和经度的值都会发生变化。这成为一个问题,因为你的 ajax 函数正在引用这个变量!因此,在实践中,这意味着您所有的网络请求都将针对相同的纬度和经度,因为循环可能在第一个 ajax 请求发送之前就已经完成了...... 执行其中一个循环大约需要 5 毫秒,发送和接收 ajax 请求大约需要 50-100 毫秒。将其设置为 async: false 有效(但它会冻结浏览器!),因为它会等到请求已发送并返回,然后再更改 latlong 变量的值。 所以,很明显,您希望 ajax 请求记住您希望它查找的值,而不是现在的内存值。解决方案是将您要使用的变量放在闭包中,以便它们保留在 ajax 函数的本地并且不会在循环的下一次迭代中被更改。

这是一个工作示例。和一个 jsfiddle:http://jsfiddle.net/47b3mjn3/2/

  function initialize() {
    var mapProp = {
        center: new google.maps.LatLng(41.8369, -95.6847),
        zoom: 4,
        disableDefaultUI: true,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    };
    map = new google.maps.Map(document.getElementById("googleMap"), mapProp);

    google.maps.event.addListener(map, 'bounds_changed', function () {
        calcBounds();
    });

    function calcBounds() {
        var bounds = map.getBounds();
        var ne = bounds.getNorthEast();
        var sw = bounds.getSouthWest();
        for (var lat = ne.lat(); lat > sw.lat(); lat = lat - 5) {
            for (var long = ne.lng(); long > sw.lng(); long = long - 5) {
                addMarker(lat, long);
            } //End Long for
        } //End lat For
    } //End function
}

function addMarker(lat, long) {
    _lat = lat;
    _long = long;
    $.ajax({
                    url: 'http://api.openweathermap.org/data/2.5/weather?lat=' + _lat + '&lon=' + _long + '&APPID=' + apiKey,
                    dataType: "json",
                    success: function (data) {
                        new google.maps.Marker({
                            map: map,
                            position: new google.maps.LatLng(_lat, _long),
                        }); //End Marker
                    }, //End Success
                    error: function () {
                        alert("ERROR");
                    }
                }); //End AJAX
}

initialize();