2017-06-12 38 views
0

我試圖提出類似的問題,並沒有得到任何幫助。 Previous QuestionJavascript - 確保geocoder循環在嵌套循環之前完成,導致markerCluster問題

取得了一些進展,發現問題在哪裏,但仍然沒有理解正確的解決方案。我已經閱讀了關於這個問題的每一個SO問題,並且瞭解到存在類似的問題,但我仍然無法弄清楚,所以建設性的反饋非常感謝:)

設置:某些用戶已經保存了緯度/經度,還有一些只有一個位置。 在將它們繪製在地圖上之前,它需要通過地理編碼器循環運行,爲任何只有位置的用戶(例如「New York,NY,United States」)創建經緯度。在所有用戶都有經緯度後,我希望他們的標記被添加到標記羣集中。

問題:在地理編碼器循環中創建的customMarkers在initMap()函數完成後運行。我已經在一個循環中嘗試了這一切(請參閱上面鏈接中的代碼)。仍然地理編碼器循環在另一個循環之後完成 - 這意味着標記是在markerCluster之後創建的,因此不是集羣。所以,現在我正在考慮拆分代碼,並確保每個函數都已完成,然後再運行下一個。

我試過幾種方法。例如是這樣的:

$.when(getMatches(map)).then(clusterUp(map, markers));

從地址解析器的customMarkers還在控制檯登錄後整個initMap()函數完成的,而現在的markercluster在initMap()函數的末尾未定義的。

如何確保在所有customMarkers創建後才創建markerCluster?

var lat 
var lng 
var userLocation 
var userId 
var markers = [] 
var geocoder = new google.maps.Geocoder() 

function getMatches(map) { 
    var matches = $.getJSON('get_json_matches', function(matches){ 
     var matches = matches 
     for(i=0; i < 11; i++) { 
      function (i) { 

      var userId = 0 
      var lat = matches[i][4]; 
      var lng = matches[i][5]; 
      var userId = matches[i][3]; 
      var userLocation = matches[i][2] 

      //If the user only has a location, make up a lat/lng  
      if (lat === null) { 
       geocoder.geocode({ 'address': userLocation }, function(results, status) { 
        if (status == google.maps.GeocoderStatus.OK) { 
         var lat = (results[0].geometry.location.lat()) + (userId * .0001); 

         var lng = (results[0].geometry.location.lng()) + (userId * .0001); 
         var marker = new CustomMarker(
          new google.maps.LatLng(lat, lng), 
          map 
         ); 
        } 
       });  
      } else { 
        var marker = new CustomMarker(
         new google.maps.LatLng(lat, lng), 
         map 
        );  
      } 
      markers.push(marker); 
      }).call(this, i); 

     } 

    return markers 

}) 
} 



function clusterUp(map, markers) { 
    console.log(markers) 
    var markerCluster = new MarkerClusterer(map, markers, 
     {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'}) 
    return markerCluster 
    console.log(markerCluster) 
} 


function initMap() { 
    var newYork = {lat: 40.7127837, lng: -74.00594130000002}; 
    var map = new google.maps.Map(document.getElementById("user-matches-map"), { 
     zoom: 12, 
     center: new google.maps.LatLng(newYork), 
     mapTypeId: google.maps.MapTypeId.ROADMAP, 
     styles: googleMapStyle 
    }); 
    var markerCluster 
    $.when(getMatches(map)).then(clusterUp(map, markers)); 
    console.log(markers) 
    console.log(markerCluster) 
} 

initMap(); 

我真的很感激一些建設性的意見。我一直在研究這一點,並認爲我錯過了一個基本概念。謝謝!!

+1

如果您確實想在執行其他代碼之前等待所有異步調用完成,您可能需要查看Promises和他的'Promise.all'方法。 – jcaron

+0

@jcaron謝謝你的建議!我沒有聽說Promise.all之前 – gwalshington

回答

1

在全局範圍內保留對MarkerClusterer的引用,然後將地理編碼器回調函數中的地理編碼器調用的標記添加到可用的地方。

geocoder.geocode({ 'address': userLocation }, function(results, status) { 
    if (status == google.maps.GeocoderStatus.OK) { 
     var lat = (results[0].geometry.location.lat()) + (userId * .0001); 

     var lng = (results[0].geometry.location.lng()) + (userId * .0001); 
     var marker = new CustomMarker(
      new google.maps.LatLng(lat, lng), 
      map 
     ); 
     // add each marker created by the geocoder callback to the clusterer as it is created. 
     markerCluster.addMarker(marker); 

    } 
}); 

// global scope 
var markerCluster = new MarkerClusterer(map, [], 
    {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'}); 

function clusterUp(map, markers) { 
    console.log(markers) 
    // add all the markers that don't require geocoding to the clusterer 
    markerCluster.addMarkers(markers); 
    console.log(markerCluster) 
} 
+0

當我把'var markerCluster'放在整個函數之外時,我得到一個錯誤:'setMap:不是Map的一個實例;' - 但是當我把它放在getMatches的內部時(map )它完美的工作!我接受了這個答案,因爲它通過小小的調整讓我得到了解決方案。非常感謝你!! – gwalshington