谷歌地图/维基百科AJAX呼叫循环问题

时间:2017-09-17 01:01:59

标签: javascript google-maps

我正在尝试使用for循环在infowindow中使用Wikipedia AJAX数据生成Google Map标记。我认为有一个时间问题,但几个星期后我无法弄清楚如何解决它。当我将标识符硬编码到for循环中以替换i(例如2)时,代码工作得很好......但是当我使用i时,我会收到错误,说“无法读取未定义的属性[无论如何”。我已经玩过setTimeout和回调,但我似乎无法弄明白。

这是我的代码:



var map;
var marker;
var infowindow;
var wikiURL;
var i;
var text;
var venueInfo;
var markers = [];
var markerNames = [];
var wikiURLs = [];
var venueArray = [];

//The Model - Pro/Collegiate Stadiums in PGH, Pa.
var venues = [
  {
    name: "PNC Park",
    lat: 40.446855,
    lng: -80.0056666
  },
  {
    name: "Heinz Field",
    lat: 40.4466765,
    lng: -80.01576
  },
  {
    name: "PPG Paints Arena",
    lat: 40.439593,
    lng: -79.989338
  },
  {
    name: "Highmark Stadium",
    lat: 40.4362358,
    lng: -80.00959209999999
  },
  {
    name: "Peterson Events Center",
    lat: 40.443828,
    lng: -79.962283
  }
];



//marker creator

function createMarker(){


for (i=0; i <= venues.length; i++){

  wikiURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=' +venues[i].name+ '&format=json&callback=wikiCallback';


  wikiURLs.push(wikiURL);

  $.ajax ({
      url: wikiURL,
      dataType: "jsonp",
      success: function(data){
            text = data[2];
            venueInfo = text[0];
            console.log(venueInfo);
            marker = new google.maps.Marker({
              position: {lat: venues[i].lat, lng: venues[i].lng},
              map: map,
              draggable: false,
              content: '<h2>'+venues[i].name+'</h2><p>'+venueInfo+'</p>'
            });


              markerNames.push(venues[i].name);
              markers.push(marker);


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



            marker.addListener('click', function(){
              infowindow.setContent(this.content);
              infowindow.open(map, this);
            });
      }

    });





}
}






//Map Initializer

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 40.446855, lng: -80.0056666},
    zoom: 14,
    mapTypeId: 'satellite'
  });
  //viewmodel();

  createMarker();

}
&#13;
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='css/bootstrap-theme.min.css'>
<link rel='stylesheet' href='css/main.css'>
</head>

<body>
  <nav>
  </nav>
  <container>
    <div id='map'>
    </div>
  </container>



  <script type='text/javascript' src='js/jquery-3.2.1.min.js'></script>
  <script type='text/javascript' src='js/knockout-3.4.2.js'></script>
  <script type='text/javascript' async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA_WObUiYD7YpoYufR84re1LZHAJeAGXkY&v=3&callback=initMap">
  </script>
  <script type='text/javascript' src='js/app.js'></script>

</body>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

正如@jeff carey所说,修复你的循环并将你的ajax代码移动到单独的函数

function doAjax(i){    

    wikiURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=' +venues[i].name+ '&format=json&callback=wikiCallback';
    wikiURLs.push(wikiURL);

    $.ajax ({
      url: wikiURL,
      dataType: "jsonp",      
      success: function(data){                  
            text = data[2];
            venueInfo = text[0];           
            marker = new google.maps.Marker({
              position: {lat: venues[i].lat, lng: venues[i].lng},
              map: map,
              draggable: false,
              content: '<h2>'+venues[i].name+'</h2><p>'+venueInfo+'</p>'
            });


              markerNames.push(venues[i].name);
              markers.push(marker);


          infowindow = new google.maps.InfoWindow({
                content: this.content
              });
          marker.addListener('click', function(){
            infowindow.setContent(this.content);
            infowindow.open(map, this);
         });
      }

    });
}

function createMarker(){ 
    for (i=0; i < venues.length; i++){      
      doAjax(i);
    }
}

答案 1 :(得分:0)

在循环中调用异步函数会导致一个常见问题。解决问题的一种方法(当回调函数运行时,i超过输入数组的末尾)是一个立即调用的函数表达式(IIFE),它保存i变量的闭包,所以当执行回调函数时,它具有&#34;正确的&#34;值:

success: (function(i) {
    return function(data) {
      text = data[2];
      venueInfo = text[0];
      console.log(venueInfo);
      marker = new google.maps.Marker({
        position: {
          lat: venues[i].lat,
          lng: venues[i].lng
        },
        map: map,
        draggable: false,
        content: '<h2>' + venues[i].name + '</h2><p>' + venueInfo + '</p>'
      });
      markerNames.push(venues[i].name);
      markers.push(marker);
      infowindow = new google.maps.InfoWindow({
        content: this.content
      });
      marker.addListener('click', function() {
        infowindow.setContent(this.content);
        infowindow.open(map, this);
      });
    }
  }(i))

proof of concept fiddle

(正常工作)代码段

&#13;
&#13;
var map;
var marker;
var infowindow;
var wikiURL;
var i;
var text;
var venueInfo;
var markers = [];
var markerNames = [];
var wikiURLs = [];
var venueArray = [];

//The Model - Pro/Collegiate Stadiums in PGH, Pa.
var venues = [{
    name: "PNC Park",
    lat: 40.446855,
    lng: -80.0056666
  },
  {
    name: "Heinz Field",
    lat: 40.4466765,
    lng: -80.01576
  },
  {
    name: "PPG Paints Arena",
    lat: 40.439593,
    lng: -79.989338
  },
  {
    name: "Highmark Stadium",
    lat: 40.4362358,
    lng: -80.00959209999999
  },
  {
    name: "Peterson Events Center",
    lat: 40.443828,
    lng: -79.962283
  }
];



//marker creator

function createMarker() {
  for (i = 0; i < venues.length; i++) {
    wikiURL = 'https://en.wikipedia.org/w/api.php?action=opensearch&search=' + venues[i].name + '&format=json&callback=wikiCallback';
    wikiURLs.push(wikiURL);
    $.ajax({
      url: wikiURL,
      dataType: "jsonp",
      success: (function(i) {
        return function(data) {
          text = data[2];
          venueInfo = text[0];
          console.log(venueInfo);
          marker = new google.maps.Marker({
            position: {
              lat: venues[i].lat,
              lng: venues[i].lng
            },
            map: map,
            draggable: false,
            content: '<h2>' + venues[i].name + '</h2><p>' + venueInfo + '</p>'
          });
          markerNames.push(venues[i].name);
          markers.push(marker);
          infowindow = new google.maps.InfoWindow({
            content: this.content
          });
          marker.addListener('click', function() {
            infowindow.setContent(this.content);
            infowindow.open(map, this);
          });
        }
      }(i))
    });
  }
}

//Map Initializer
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: 40.446855,
      lng: -80.0056666
    },
    zoom: 14,
    mapTypeId: 'satellite'
  });
  //viewmodel();
  createMarker();
}
&#13;
html,
body,
#map {
  height: 100%;
  width: 100%;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<container>
  <div id='map'>
  </div>
</container>
<script type='text/javascript' async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>
&#13;
&#13;
&#13;