2017-01-12 4 views
0

Итак, я тестирую скрипт, что бы взять города из массива, затем найти их координаты с геокодом и после этого получить почтовый индекс города. Ну, это работает нормально с одним городом, но с массивом, geoCode имеет ограничение по запросу, поэтому я пытаюсь обойти его с помощью setTimeout, но, поскольку я еще не удивлен в js, он не работает. Обход ограничения на геокодирование с помощью setimeout

<head> 
    <div id= "test"></div> 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 

    <script type="text/javascript"> 

    function getLoc(){ 
     var geocoder = new google.maps.Geocoder(); 
     var address = ["Helsinki", "Paris", "London"]; 
     for (var i = 0; i < address.length; i++) { 
      setTimeout(function(i){ 
      geocoder.geocode({ 'address': address[i]}, function (results, status) {  
      if (status == google.maps.GeocoderStatus.OK) { 
       var lat = results[0].geometry.location.lat(); 
       var long = results[0].geometry.location.lng(); 
       alert(long); 
       getZip(lat, long); 

       } 
      }); 
      }, i* 1000); 
     } 
     } 
     getLoc(); 
    function getZip(lat, long){ 
     var latlng = new google.maps.LatLng(lat, long); 
     geocoder.geocode({ 
     'latLng': latlng 
     }, function(results, status) { 
      address = results[0].address_components; 
      zipcode = address[address.length - 1].long_name; 
      document.getElementById("test").innerHTML = zipcode; 
     }); 
    } 
</script> 
</head> 
<body> 

</body> 

+0

Я считаю, что вы видите широты и долго последний город «Лондон»? –

+0

таймаут работает, но он не проходит первый запрос геокода – Skyhigh17

+0

Я не знаю ваш случай использования или размер вашего набора данных, но вы можете подумать о написании задания cron на стороне сервера, которое извлекает данные в фоновом режиме (с соответствующий дроссель) и сохраняет его в базе данных. Ограничения API слишком низки для пакетной обработки в режиме реального времени, и добавление преднамеренной задержки на клиенте может привести к разочарованию посетителей. –

ответ

3
for (var i = 0; i < address.length; i++) { 
(function(i){ 
    setTimeout(function(i){ 
    geocoder.geocode({ 'address': address[i]}, function (results, status) { if (status == google.maps.GeocoderStatus.OK) { var lat = results[0].geometry.location.lat(); var long = results[0].geometry.location.lng(); alert(long); getZip(lat, long); } }); 
    }, i* 1000); 
    })(i); 
} 

для цикла завершится до таймаутов пожара. Поэтому я всегда буду adress.length-1 во всех таймаутах. Вам нужно хранить i в каждой области тайм-аутов с использованием IIFE (возможно, посмотрите на «таймауты в цикле for» на SO)

Как отметил @iwrestledabearonce, использование тайм-аута - не изящный способ. Вы могли либо использовать несколько открытых запросов одновременно, либо один за другим. Для первого вам не нужен тайм-аут, а для второго рекурсивная функция - более элегантное решение.

3

Вы должны wrapp своего setTimeout в функции замыкания, например:

for (var i = 0; i < address.length; i++) { 
    (function(i){ 
     setTimeout(function(i){ 
      geocoder.geocode({ 'address': address[i]}, function (results, status) {  
       if (status == google.maps.GeocoderStatus.OK) { 
        var lat = results[0].geometry.location.lat(); 
        var long = results[0].geometry.location.lng(); 
        alert(long); 
        getZip(lat, long); 

       } 
      }); 
     }, i* 1000); 
    })(i); 
} 

без закрытия вашей i в setTimeout будет всегда имеет значение от последнего for итерация

+0

почему кто-то минус этот ответ ...? –

+0

Не знаю, я еще не успел попробовать. – Skyhigh17

+0

Я объяснил, почему этот ответ и тот, что выше, ошибочны в моем собственном ответе. вопрос в том, почему кто-то поднял неправильный ответ? –