遍历数组javascript google maps标记

遍历数组javascript google maps标记,javascript,ruby-on-rails,ruby,google-maps,Javascript,Ruby On Rails,Ruby,Google Maps,问题的背景 我有一个包含纬度和经度值的数组。我有下面的代码,为每个迭代放置一个标记。我使用Ruby gem将值从数据库传递到javascript。以下各项按预期工作: function populateMap(map){ var index; for (index = 0; index < gon.length; ++index) { var latlng = new google.maps.LatLng(gon.murals[index].lat, gon.m

问题的背景

我有一个包含纬度和经度值的数组。我有下面的代码,为每个迭代放置一个标记。我使用Ruby gem将值从数据库传递到javascript。以下各项按预期工作:

function populateMap(map){
    var index;
    for (index = 0; index < gon.length; ++index) {
      var latlng = new google.maps.LatLng(gon.murals[index].lat, gon.murals[index].long);
      var marker = new google.maps.Marker({
        position: latlng,
        map: map  
      }); 
    }
  }         
实际问题 当我将for循环添加到reverse geo0code函数时,它只放置上一次迭代的标记

   function populateMapTest(map, geocoder, infowindow){
    var index;
    for (index = 0; index < gon.murals.length; ++index) {
      var latlng = new google.maps.LatLng(gon.murals[index].lat, gon.murals[index].long);
      alert("start of iteration: " + index);
      geocoder.geocode({'location': latlng}, function(results, status){
        alert("middle of iteration: " + index);
        if (status === 'OK') {
          if (results[1]) {
            var marker = new google.maps.Marker({
              position: latlng,
              map: map
            });

            google.maps.event.addListener(marker, 'mouseover', function () {
              infowindow.open(map, marker);
              document.getElementById("address").innerHTML = results[1].formatted_address ;

            });

          } else {
              window.alert('No results found'); 
            }
        } else {
            window.alert('Geocoder failed due to: ' + status);
          }

      });

      alert("end of iteration: " + index);
    }  
  } 
对于每个迭代,警报的顺序如下:迭代开始、迭代结束、迭代中间。它似乎在跳过地理编码器括号中包含的代码,直到完成所有迭代。我想是吧


谢谢你的帮助

这听起来像是一个类闭包问题,它涉及到一个变量的作用域,该变量在高作用域中声明,但在低作用域的函数中使用,并且比实际声明该变量的高作用域持续时间更长

更改:

var index;
for (index = 0; index < gon.murals.length; ++index) {
致:

这将给出索引块级别的范围,循环的每个迭代都有自己的索引值。不是所有循环的迭代都共享相同的索引值,而是每个循环都有自己的索引值。

这样如何:

geocoder.geocode({'location': latlng}, (function(indexCopy){
  return function(results, status) {
    alert("middle of iteration: " + indexCopy);
    if (status === 'OK') {
      if (results[1]) {
        var marker = new google.maps.Marker({
          position: latlng,
          map: map
        });

        google.maps.event.addListener(marker, 'mouseover', function () {
          infowindow.open(map, marker);
          document.getElementById("address").innerHTML = results[1].formatted_address ;
        });

      } else {
        window.alert('No results found'); 
      }
    } else {
      window.alert('Geocoder failed due to: ' + status);
    }

  };
})(index));

只是一个想法…

这似乎是一个结束问题。但我认为这可能是因为变量latlng而不是索引,或者两者兼而有之

var latlng = new google.maps.LatLng(gon.murals[index].lat, gon.murals[index].long);
上面的latlng会在整个循环中更新,但最终函数只使用最后一次迭代的latlng。中间函数的闭包内的变量被引用,当函数实际执行时,所有变量都将更新为最后一个值。我想另一种思考方式是,它实际上只在执行过程中查看值,而不是声明

 var marker = new google.maps.Marker({
          position: latlng,
          map: map
        });
最后,标记将在相同的位置创建,索引时间

例如,下面的代码将打印10个9,即使您希望它打印递增的x

但是,如果它被立即调用,这将正确地打印它,但当然,这不是您的案例的选项

function foo() {
  for (let index = 0; index < 10; ++index) {
    var x = index;
    setTimeout(function bar() {
      console.log(x)
    }(), 10)
  }
}
foo()

您可以将latlng声明移动到中间函数中。不过也要检查索引的值,因为这会遇到同样的问题

谢谢你的评论,但它的行为与我的做法完全相同。它会在每次迭代中进行,然后在最后执行“中间部分.geocoder.geocode”似乎是异步的,因此中间迭代似乎总是在迭代结束后运行,例如在迭代结束后。
 var marker = new google.maps.Marker({
          position: latlng,
          map: map
        });
function foo() {
  for (let index = 0; index < 10; ++index) {
    var x = index;
    setTimeout(function bar() {
      console.log(x)
    }, 10)
  }
}
foo()
function foo() {
  for (let index = 0; index < 10; ++index) {
    var x = index;
    setTimeout(function bar() {
      console.log(x)
    }(), 10)
  }
}
foo()