Javascript Loop пропускает значения массива - PullRequest
0 голосов
/ 29 октября 2018

Я пытаюсь сделать цикл for с javascript, чтобы перебрать массив и вывести значения для каждого массива. Он ищет расстояние и продолжительность, используя Google API матрицы расстояния.

Мой код здесь: https://codepen.io/claireben/pen/oaVoNG

var placesdest = ["11205", "11230", "11204", "11234", "33140", "90086"];
$(function() {
  for (var i = 0; i <= 6; i++) {

    function calculateDistance(origin, destination) {
      var service = new google.maps.DistanceMatrixService();
      service.getDistanceMatrix({
        origins: [origin],
        destinations: [destination],
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.IMPERIAL,
        avoidHighways: false,
        avoidTolls: false
      }, callback);
    }

    function callback(response, status) {
      if (status != google.maps.DistanceMatrixStatus.OK) {
        $('.result').html(err);
      } else {
        var origin = response.originAddresses[0];
        var destination = response.destinationAddresses[0];
        if (response.rows[0].elements[0].status === "ZERO_RESULTS") {
          $('.result').html("Better get on a plane. There are no roads between " +
            origin + " and " + destination);
        } else {
          var distance = response.rows[0].elements[0].distance;
          var distance_value = distance.value;
          var distance_text = distance.text;
          var duration = response.rows[0].elements[0].duration;
          var duration_value = duration.value;
          var duration_text = duration.text;
          var miles = distance_text.substring(0, distance_text.length - 3);
          if (duration_value < 3600) {
            $('.result').html("It is " + distance_text + " from " + origin + " to " + destination + " AND " + duration_text);
          }
        }
      }
    }

    /*$('#distance_form').submit(function(e){
        event.preventDefault();
        var origin = $('#origin').val();
        var destination = $('#destination').val();
        var distance_text = calculateDistance(origin, destination);
    });*/

    //var origin = document.getElementById("originq").innerHTML;
    var origin = "1762 Gerritsen Ave Brooklyn, New York 11229";
    // var destination = document.getElementById("destinationq").innerHTML;
    var destination = placesdest[i];
    var distance_text = calculateDistance(origin, destination);

    var para = "<div class='result'></div>";
    $("body").append(para);
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<h2>Distance Between two Addresses</h2>
<!--<form id="distance_form">
    <label>Origin: </label>
    <input id="origin" type="text" name="origin"/>
    <br/>
    <label>Destination: </label>
    <input id="destination" type="text" name="destination"/>
    <br/>
    <input type="submit" value="Calculate"/>
</form>-->
<div id="originq">1762 Gerritsen Ave Brooklyn, New York 11229
</div><div id="destinationq">1507 Coney Island Ave, Brooklyn, NY 11230
</div>

<div id="resultdura">
</div>

Проблема в том, что он не перебирает весь массив. Кажется, он выбирает один случайный.

Я новичок в JavaScript. Любая помощь с благодарностью.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Проблема, с которой вы сталкиваетесь с вашим кодом, связана с асинхронной природой вашего цикла, а не с его обработкой каким-либо образом. Есть много библиотек, парадигм и т. Д., Чтобы работать с этой проблемой, но это то, что вам нужно взять в свои руки, чтобы стать профессионалом javascript. Я постараюсь описать проблему, чтобы вы могли попытаться решить ее в контексте своего кода, а не показывать вам все эти подходы.

Сначала я опишу, что происходит, когда вы запускаете этот цикл - он запустит 6 запросов, но когда эти запросы возвращаются с ответными данными и с каким ответом зависит, какой запрос решать вам.

Когда ваш запрос запускается из цикла, вы вызываете свой асинхронный блок следующим образом: calculateDistance(origin,destination), который затем запускает функцию обратного вызова, когда запрос завершен, как ваш исходный цикл передается в функцию CalculateDistance, которая вызывает обратный вызов какой запрос идет с каким результатом? Это не так.

Глядя на существующий код, функция 'init ()', которая запускает цикл, должна по крайней мере передать индексную переменную i в функцию calculateDistance(index,origin,distance), которая затем гипотетически даст вам возможность передать ее в функция обратного вызова, поэтому она может соответствовать результату. Вы можете иметь пустой массив с таким же размером, называемым results, и в вашей функции обратного вызова, если вы передадите туда индексную переменную callback(response,status,index), вы можете установить результат с помощью results[index] = response. Затем вам нужно будет отследить, когда все запросы выполнены, а затем отрендерить их.

Во всяком случае, это то, что здесь происходит, это асинхронная проблема. Там есть много прочтений, и это одна из сложных вещей в кодировании с использованием JavaScript. Javascript является однопоточным, поэтому важно понимать асинхронные парадигмы, я не буду описывать все это здесь.

0 голосов
/ 30 октября 2018

Надеюсь, это поможет вам

объявляет функции перед циклом for

var placesdest = ["11205", "11230", "11204", "11234", "33140", "90086"];
function calculateDistance(origin, destination) {
  var service = new google.maps.DistanceMatrixService();
  service.getDistanceMatrix(
    {
      origins: [origin],
      destinations: [destination],
      travelMode: google.maps.TravelMode.DRIVING,
      unitSystem: google.maps.UnitSystem.IMPERIAL,
      avoidHighways: false,
      avoidTolls: false
    }, callback);
}

function callback(response, status) {
  if (status != google.maps.DistanceMatrixStatus.OK) {
    $('.result').html(err);
  } else {
    var origin = response.originAddresses[0];
    var destination = response.destinationAddresses[0];
    if (response.rows[0].elements[0].status === "ZERO_RESULTS") {
      $('.result').html("Better get on a plane. There are no roads between " 
                    + origin + " and " + destination);
    } else {
      var distance = response.rows[0].elements[0].distance;
      var distance_value = distance.value;
      var distance_text = distance.text;
      var duration = response.rows[0].elements[0].duration;
      var duration_value = duration.value;
      var duration_text = duration.text;
      var miles = distance_text.substring(0, distance_text.length - 3);
      // you are validating the duration_value to be more 3600 to be able print
      if (duration_value < 3600) {
        $('#resultdura').append("It is " + distance_text + " from " + origin + " to " + destination + " AND " + duration_text + " <br>");
      }
    }
  }
}

, а затем создайте функцию для вызова for

function init () {
  for (var i=0; i < placesdest.length; i++) {
    //var origin = document.getElementById("originq").innerHTML;
    var origin = "1762 Gerritsen Ave Brooklyn, New York 11229";
     // var destination = document.getElementById("destinationq").innerHTML;
    var destination = placesdest[i];
    var distance_text = calculateDistance(origin, destination);
  }
}

наконец вызовите метод init для инициализации скрипта

init()
  • Помните, что вы проверяете продолжительность печати, это означает, что не все адресаты будут напечатаны, если их продолжительность меньше 3600
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...