Почему глобальная переменная внутри для l oop не меняет значение? Javascript - PullRequest
0 голосов
/ 21 апреля 2020

У меня проблема при выполнении функции, которая запускает для l oop с 3 глобальными переменными, которые будут переданы в функцию обратного вызова. Все массивы имеют одинаковую длину, проблема состоит в том, что 3 переменные окна, вызываемые в getPickup() внутри функции обратного вызова, не изменяют значение ни в одном из операций l oop. Я нахожу это странным, потому что эти переменные должны получить новое значение, обновленное с location, когда функция обратного вызова завершится, и l oop будет запущен снова.

function calculateDistanceDriverCustomer() {
       {% autoescape off %}
       var locations = {{ locations }}
       {% endautoescape %}

       {% autoescape off %}
       var firstname = {{ firstname }}
       {% endautoescape %}

       {% autoescape off %}
       var lastname = {{ lastname }}
       {% endautoescape %}

       {% autoescape off %}
       var rating = {{ rating }}
       {% endautoescape %}
       var location;
       for (location = 0; location < locations.length; location++) {
        var origin = locations[location];
        window.firstname = firstname[location];
        window.lastname = lastname[location];
        window.rating = rating[location];
        var destination = $('#origin-input').val();
        var service = new google.maps.DistanceMatrixService();
        service.getDistanceMatrix(
                {
                    origins: [origin],
                    destinations: [destination],
                    travelMode: google.maps.TravelMode.DRIVING,
                    unitSystem: google.maps.UnitSystem.METRIC, // kilometers and meters.
                    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 {
                        //get estimated pickup time if distance less or equal than 10km
                    function getPickup() {
                        var distance = response.rows[0].elements[0].distance;
                        var duration = response.rows[0].elements[0].duration;
                        var distance_in_kilo = distance.value / 1000;
                        var duration_value = duration.value*1000;
                        console.log(distance_in_kilo);
                        var time = new Date()
                        time = new Date(time.getTime() + duration_value);
                        var date = new Date(time)
                        var currenthr = date.getHours()
                        var currentmin = date.getMinutes()
                        var currentsec = date.getSeconds()
                        if (currenthr   < 10) {currenthr   = "0"+currenthr;}
                        if (currentmin < 10) {currentmin = "0"+currentmin;}
                        if (currentsec < 10) {currentsec = "0"+currentsec;}
                        window.pickupTime = currenthr + ":" + currentmin + ":" + currentsec;
                        console.log(pickupTime);
                        if (distance_in_kilo <= 3000) {
                            var name = document.createElement("hd");
                            var brk = document.createElement("br");
                            var node = document.createTextNode(window.firstname + " " + 
                            window.lastname);
                            name.appendChild(node);
                            var element = document.getElementById("cars");
                            element.appendChild(name);
                            element.appendChild(brk);
                            var pickup = document.createElement("hd");
                            var node1 = document.createTextNode("Pickup Time: " + window.pickupTime);
                            pickup.appendChild(node1);
                            var element1 = document.getElementById("cars");
                            element1.appendChild(pickup);
                            element1.appendChild(brk);
                            var rating = document.createElement("hd");
                            var node3 = document.createTextNode("rating: " + window.rating);
                            rating.appendChild(node3);
                            var element3 = document.getElementById("cars");
                            element3.appendChild(rating);
                            element3.appendChild(brk);
                        }
                        else {
                            console.log("Not available");
                        }

                     }
                    getPickup();
                }
            }
        };

Переменные определены в начале для l oop они window.firstname, window.lastname и window.rating. Они получают значение из массива, содержимое которого было передано из python (определено в начале calculateDistanceDriverCustomer(). Это код python:

 cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
    cursor.execute("SELECT CurrentLocation, FirstName, LastName, OverallRating FROM driver WHERE OnJourney=0")
    rows = cursor.fetchall()  # data from database
    locations = []
    firstname = []
    lastname = []
    rating = []
    for row in rows:
        locations.append(row['CurrentLocation'])
        firstname.append(row['FirstName'])
        lastname.append(row['LastName'])
        rating.append(row['OverallRating'])
    return render_template("Search.html", rows=rows, locations=locations, firstname=firstname, lastname=lastname, rating=rating)

Спасибо за вашу помощь

1 Ответ

0 голосов
/ 21 апреля 2020

Я не знаю Django, но обратный вызов getDistanceMatrix, вероятно, выполняется асинхронно. Это означает, что ваш for-l oop уже завершен, когда сработает первый обратный вызов. В результате во всех обратных вызовах используются значения window.firstname, window.lastname и window.rating, которые установлены последней итерацией из l oop.

Если это действительно проблема вы можете решить это, передав вместо них callback параметры.

Затем примите эти параметры в вашем обратном вызове:

function callback(response, status, data) {
  // ...
  var node = document.createTextNode(`${data.firstname} ${data.lastname}`);
  // ...
}

Я бы также порекомендовал переместить такие вещи, как new google.maps.DistanceMatrixService() и $('#origin-input').val() за пределами -l oop. Они не зависят от повторяющихся элементов и создаются больше, чем нужно. (Если locations содержит 100 элементов, вы создаете 100 new google.maps.DistanceMatrixService(), а вам, скорее всего, нужно только 1.) Я исключил это из примера кода, так как нет необходимости исправлять ваш код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...