Javascript 如何从for语句中的异步回调中获得结果

Javascript 如何从for语句中的异步回调中获得结果,javascript,asynchronous,Javascript,Asynchronous,我想显示ajax post mysql查询的结果,并通过结果进一步细化到getDistanceMatrix,这是一个异步函数,作为回调的一部分返回距离值 我读过几篇关于异步函数(如等)的文章,选择使用回调作为最简单的理解方法,但无法使其工作,因此遇到了麻烦 我正在使用javascript和一些php,如果我不运行getDistanceMatrix,它就可以显示结果,但无法计算出如何从函数中获取kms值以供if语句使用,从而进一步优化要显示的结果。 我也尝试过在回调函数callbacku calc

我想显示ajax post mysql查询的结果,并通过结果进一步细化到getDistanceMatrix,这是一个异步函数,作为回调的一部分返回距离值

我读过几篇关于异步函数(如等)的文章,选择使用回调作为最简单的理解方法,但无法使其工作,因此遇到了麻烦

我正在使用javascript和一些php,如果我不运行getDistanceMatrix,它就可以显示结果,但无法计算出如何从函数中获取kms值以供if语句使用,从而进一步优化要显示的结果。 我也尝试过在回调函数callbacku calcDistancekms中包含if语句和表html,但是没有显示任何内容。 我认为问题在于代码在getDistanceMatrix完成之前就已经完成了,但是不知道如何及时从这个函数中获得运行html表的结果。 我已经包括了下面的javascript部分

` $document.readyfunction{

$("#findride").submit(function(){
//js variables from form
  $.ajax({
    url: 'includes/findride.inc.php',
    type: 'POST',
    dataType:"json",
    data: { rdate:rdate, rtime:rtime, },
    success: function(data) {
    //isEmpty function
      if(isEmpty(data)) {
          $("#result").html("<p class='loginError' >No Rides match your Search</p>");
      }
      else
      {
        var output =
          "<table><thead><tr><th class='tablehdr-15'>Ride ID</th><th class='tablehdr-60'>Destination</th><th class='tablehdr-25'>Arrival Time</th></thead><tbody>";

        for (var i in data) {

          var driver_lng = data[i].user_lng;
          // other variables from mysql

          var origin = new google.maps.LatLng(-36.78961120, 174.75189440);
          var destination = new google.maps.LatLng(-36.80272570, 174.74423420);
          var distanceResult1;

          function calcDistance (fromLat, fromLng, toLat, toLng) {
            return  google.maps.geometry.spherical.computeDistanceBetween(
              new google.maps.LatLng(fromLat, fromLng), new google.maps.LatLng(toLat, toLng));
          }

          var calcD = calcDistance(latdb, lngdb, lats, lngs);

          calculateDistanceDriver(origin, destination, Callback_calcDistance);

          function calculateDistanceDriver(origin, destination, ref_Callback_calcDistance) {
            var service = new google.maps.DistanceMatrixService();
            var kms;

            service.getDistanceMatrix(
            {
              origins: [origin],
              destinations: [destination],
              travelMode: google.maps.TravelMode.DRIVING,
              unitSystem: google.maps.UnitSystem.METRIC
            }, function (response, status) {
              if (status != google.maps.DistanceMatrixStatus.OK) {
                $('#result1').html(err);
              }
              else
              {
                var origin = response.originAddresses[0];
                var destination = response.destinationAddresses[0];
                if (response.rows[0].elements[0].status === "ZERO_RESULTS") {
                  $('#result1').html("No result for this search");
                }
                else
                {
                  var distance = response.rows[0].elements[0].distance;
                  var distance_value = distance.value;
                  var distance_text = distance.text;
                  var kms = distance_text.substring(0, distance_text.length - 3);

                  //How can I make kms available for the if ((calcD < 2000) .. statement below?

                  $('#result1').html("Result = " + kms);
                  console.log("distance result a " + kms);
                  if(typeof ref_Callback_calcDistance === 'function'){

                      ref_Callback_calcDistance(kms)
                  }
                }
              }
            });
          }
          function Callback_calcDistance(kms) {
              console.log("distanceResult " + kms);
              distanceResult1 = kms;
          }
          console.log("distanceResult1 " + distanceResult1);



          //I want to use kms here for following if statement

          // if ((calcD < 2000) && (seatsreq <= freeseats) && (distanceResult1 <= extra_dist)) {
          if ((calcD < 2000) && (seatsreq <= freeseats)) {
            output +=
              "<tr><td class='tablehdr-15'>" +
              data[i].ride_id +
              "</td><td class='tablehdr-60'><a href='includes/ridedetails.inc.php?rideid=" + data[i].ride_id + "' target='_blank'>" +
              data[i].dest_address +
              "</a></td><td class='tablehdr-25'>" +
              data[i].ride_time +
              "</td></tr>";
          }
        }
        output += "</tbody></table>";
        $("#result").html(output);
        $("table").addClass("table-300");
      }
    },
    error: function(e) {
    console.log(e.message);
    }
  });
  event.preventDefault();
});
}); `


我希望能够使用getDistanceMatrix调用的结果进一步细化ajax帖子中的结果。

在全局中声明var kms,然后您将获得kms值


Callback\u calcDistance函数未调用,因此请检查。

以下是解决方案。我在回调中移动了if语句,并创建了第二个输出变量作为新表

<main>
          <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
            <script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places,geometry&callback=initAutocomplete"
            async defer></script>

            <script>
                $(document).ready(function(){

                    $("#findride").submit(function(){

                        var rdate = $("#rdate").val();
                        var rtime = $("#rtime").val();
                        console.log(rtime);
                        console.log(rdate);
                        var lats = $("#lat").val();
                        var lngs = $("#lng").val();
                        var seatsreq = $("#seatsreq").val();
                        var kms;

                        $.ajax({
                          url: 'includes/findride1.inc.php',
                          type: 'POST',
                            dataType:"json",
                          data: {   rdate:rdate, rtime:rtime, seatsreq:seatsreq },
                          success: function(data) {
                                console.log(data);

                                function isEmpty(obj) {
                                        for(var key in obj) {
                                                if(obj.hasOwnProperty(key))
                                                        return false;
                                        }
                                        return true;
                                }

                                if(isEmpty(data)) {
                                        $("#result").html("<p class='loginError' >No Rides match your Search</p>");
                                }
                                else
                                {
                                    var output =
                                        "<table><thead><tr><th class='tablehdr-15'>Ride ID</th><th class='tablehdr-60'>Destination</th><th class='tablehdr-25'>Arrival Time</th></thead><tbody></tbody></table>";

                                        $("#result").html(output);
                                        $("table").addClass("table-300");
                                        //$("#result").hide();
                                    var output1 = "<table><tbody>";

                                    for (let i in data) {
                                        var latdb = data[i].lat;
                                        var lngdb = data[i].lng;

                                        var extra_dist = data[i].extra_dist;
                                        var freeseats = data[i].free_seats;
                                        var driver_lat = data[i].user_lat;
                                        var driver_lng = data[i].user_lng;
                                        var driver_dist = data[i].driver_dist;

                                        var origin = new google.maps.LatLng(-36.78961120, 174.75189440);
                                        var destination = new google.maps.LatLng(-36.80272570, 174.74423420);

                                        var origin1 = "-36.78961120, 174.75189440";
                                        var destination1 = "-36.80272570, 174.74423420";

                                        var distanceResult1;
                                        var directionsService = new google.maps.DirectionsService();
                                        var service = new google.maps.DistanceMatrixService();

                                        var calcD = calcDistance(latdb, lngdb, lats, lngs);

                                        function calcDistance (fromLat, fromLng, toLat, toLng) {
                                      return  google.maps.geometry.spherical.computeDistanceBetween(
                                        new google.maps.LatLng(fromLat, fromLng), new google.maps.LatLng(toLat, toLng));
                                    }

                                        calcRoute();

                                        function calcRoute() {
                                          var waypts = [
                                                {
                                                    location: "-36.7612802,174.7516339",
                                                    stopover: true
                                                }
                                            ];

                                          var request = {
                                            origin: origin1,
                                            destination: destination1,
                                            waypoints: waypts,
                                            optimizeWaypoints: false,
                                            travelMode: google.maps.TravelMode.DRIVING,
                                                unitSystem: google.maps.UnitSystem.METRIC
                                          };

                                          directionsService.route(request, function(response, status) {
                                            if (status == google.maps.DirectionsStatus.OK) {

                                              var total_distance = 0.0;
                                              for (var i=0; i<response.routes[0].legs.length; i++) {
                                                total_distance += response.routes[0].legs[i].distance.value;
                                                }
                                              console.log("distance value " + total_distance);
                                            }
                                          });
                                        }

                                        calculateDistanceDriver(origin, destination, Callback_calcDistance);

                                        function calculateDistanceDriver(origin, destination, ref_Callback_calcDistance) {

                                            service.getDistanceMatrix(
                                            {
                                                origins: [origin],
                                                destinations: [destination],
                                                travelMode: google.maps.TravelMode.DRIVING,
                                                unitSystem: google.maps.UnitSystem.METRIC,
                                                avoidHighways: false,
                                                avoidTolls: false
                                            }, function (response, status) {
                                                if (status != google.maps.DistanceMatrixStatus.OK) {
                                                    $('#result1').html(err);
                                                }
                                                else
                                                {
                                                    var origin = response.originAddresses[0];
                                                    var destination = response.destinationAddresses[0];
                                                    if (response.rows[0].elements[0].status === "ZERO_RESULTS") {
                                                        $('#result1').html("No result for this search");
                                                    }
                                                    else
                                                    {
                                                        var distance = response.rows[0].elements[0].distance;
                                                        var distance_value = distance.value;
                                                        var distance_text = distance.text;
                                                        var kms = distance_text.substring(0, distance_text.length - 3);

                                                        //$('#result1').html("Result = " + kms);
                                                        // console.log("distance result a " + kms);
                                    if(typeof ref_Callback_calcDistance === 'function'){

                                        ref_Callback_calcDistance(kms)
                                    }
                                                    }
                                                }
                                            });
                                        }
                                        function Callback_calcDistance(kms) {

                                            distanceResult1 = kms;

                                            if ((calcD < 2000) && (distanceResult1 <= extra_dist)) {
                                                console.log("distanceResult1 <= extra_dist & calD" + data[i].ride_id);
                                                output1 +=
                                                    "<tr><td class='tablehdr-15'>" +
                                                    data[i].ride_id +
                                                    "</td><td class='tablehdr-60'><a href='includes/ridedetails.inc.php?rideid=" + data[i].ride_id + "' target='_blank'>" +
                                                    data[i].dest_address +
                                                    "</a></td><td class='tablehdr-25'>" +
                                                    data[i].ride_time +
                                                    "</td></tr>";
                                                    $("#result1").html(output1);
                                                $("#infotext").html("The following rides meet your search criteria. Click on the ride to get more information");

                                            } else {
                                                //$("#result").html("<p class='loginError' >No Rides match your Search</p>");
                                            }
                                        }
                                    }
                                    var output2 = "</tbody></table>";
                                    $("#result2").html(output2);

                                    //$("table").addClass("table-300");
                                }
                          },
                          error: function(e) {
                            console.log(e.message);
                          }
                        });
                        event.preventDefault();
                    });
                });
            </script>
            <div class="main-wrapper">
                <h3 class="h3-heading">Find Ride</h3>

                <form class="form-wrapper" id="findride" action="includes/findride.inc.php" method="post">

                    <p class="pTextsm">Date of Travel</p>
              <input class="def-form" type="date" id="rdate" name="rdate"><br>
                    <p class="pTextsm">Arrival Time at Destination</p>
              <input class="def-form" type="time" id="rtime" name="rtime" value="12:00"><br>
                    <p class="pTextsm">Seats required</p>
                    <input class="def-formB" type="text" id="seatsreq" name="seatsreq"><br>
                    <p class="pTextsm">Destination Address (if no result enter surburb and map will display. Then place marker to get address) </p>
                    <input class="def-form" type="text" id="autocomplete" onFocus="geolocate()" name="address"><br>
                    <div id="maprd" style="display: none;"></div>
                    <!-- <p class="pTextsm">Pick up Address</p>
                    <p class="pTextsm" id="addresspickupdef"></p>
                    <p class="pTextsm">(enter only if different from your Account Address)</p>
                    <input class="def-form" type="text" id="autocompletepickup" onFocus="geolocate()" name="pickupaddress"><br> -->
                    <input type="hidden" id="place_id" name="place_id" value="test">
                    <input type="hidden" id="lat" name="lat">
                    <input type="hidden" id="lng" name="lng">
                    <input type="hidden" id="place_idpickup" name="place_idpickup" value="test">
                    <input type="hidden" id="latpickup" name="latpickup">
                    <input type="hidden" id="lngpickup" name="lngpickup">
                    <!-- <input type="hidden" id="seatsreq" name="seatsreq"> -->
                    <input type="hidden" id="latlngnew" type="text" value="40.714224,-73.961452">
                    <button class="def-form-button" type="submit" id="ridesub" name="ridesub">Find Ride</button>
                </form>
                <div id="infotext"></div>
                <div id="result"></div>
                <div id="result1"></div>
                <div id="result2"></div>
                <div id="norides"></div>
                <div id="placeidshow"></div>
                <div id="latsdiv"></div>
                <div id="lngsdiv"></div>
                <div id="latdbdiv"></div>
                <div id="lngdbdiv"></div>
                <div id="calcDdiv"></div>
                <div id="calcseatsavail"></div>
                <div id="seatsreq1"></div>


            </div>
        </main>
        <script>

            var placeSearch, autocomplete, autocompletepickup, placeId, placeIdpickup;

            function initAutocomplete() {

                autocomplete = new google.maps.places.Autocomplete(
                        /** @type {!HTMLInputElement} */(document.getElementById('autocomplete')),
                        {types: ['geocode']});

                autocomplete.setComponentRestrictions(
            {'country': ['nz']});

                autocomplete.addListener('place_changed', fillInAddress);

                autocompletepickup = new google.maps.places.Autocomplete(
                        /** @type {!HTMLInputElement} */(document.getElementById('autocompletepickup')),
                        {types: ['geocode']});

                autocompletepickup.setComponentRestrictions(
            {'country': ['nz']});

                autocompletepickup.addListener('place_changed', fillInAddresspickup);
            }

            function fillInAddress() {

                var place = autocomplete.getPlace();
                var lat = place.geometry.location.lat();
        var lng = place.geometry.location.lng();

                document.getElementById('lat').value = lat;
                document.getElementById('lng').value = lng;

                placeId = place.place_id;
                document.getElementById('place_id').value = placeId;

                $("#maprd").css("display", "block");
                myMap(lat,lng);
                //$('#placeidshow').html(lat);
            }

            function fillInAddresspickup() {

                var place = autocompletepickup.getPlace();
                var lat = place.geometry.location.lat();
        var lng = place.geometry.location.lng();

                document.getElementById('latpickup').value = lat;
                document.getElementById('lngpickup').value = lng;

                placeId = place.place_id;
                document.getElementById('place_idpickup').value = placeId;
                //$('#placeidshow').html(lat);
            }

            function geolocate() {
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(function(position) {
                        var geolocation = {
                            lat: position.coords.latitude,
                            lng: position.coords.longitude
                        };
                        var circle = new google.maps.Circle({
                            center: geolocation,
                            radius: position.coords.accuracy
                        });
                        autocomplete.setBounds(circle.getBounds());
                    });
                }
            }
        </script>
        <script>
            var map, marker, newmarker, geocoder, infowindow, newmarkerlat, newmarkerlng;
                function myMap(lat,long) {
                    var myCenter = new google.maps.LatLng(lat,long);
                    var mapCanvas = document.getElementById("maprd");

                    var mapOptions = {
                            center: myCenter,
                            zoom: 18
                            // streetViewControl: false,
                            // mapTypeControl: false
                    };

                    map = new google.maps.Map(mapCanvas, mapOptions);
                    marker = new google.maps.Marker(
                            {
                                    position:myCenter,
                                    draggable: true
                            }
                    );
                    marker.setMap(map);

                    google.maps.event.addListener(marker,'click',function() {
                            //map.setZoom(12);
                            map.setCenter(marker.getPosition());
                    });

                    google.maps.event.addListener(map, 'click', function(event) {
                        newmarkerlat = event.latLng.lat();
                        newmarkerlng = event.latLng.lng();
                        var newmarkerlatlng = "" + newmarkerlat + "," + newmarkerlng;
                        document.getElementById('latlngnew').value = newmarkerlatlng;
                        placeMarker(map, event.latLng);

                        // console.log(document.getElementById('latlngnew').value);
                    });

                }

            function placeMarker(map, location) {
              var marker = new google.maps.Marker({
                position: location,
                map: map
              });

                infowindow = new google.maps.InfoWindow;
                geocoder = new google.maps.Geocoder;
                geocodeLatLng(geocoder, map, infowindow);

            }

            function geocodeLatLng(geocoder, map, infowindow) {
        var input = document.getElementById('latlngnew').value;
        var latlngStr = input.split(',', 2);
        var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};

        geocoder.geocode({'location': latlng}, function(results, status) {
          if (status === 'OK') {
            if (results[0]) {
              //map.setZoom(11);
              var marker = new google.maps.Marker({
                position: latlng,
                map: map
              });
              infowindow.setContent(results[0].formatted_address);
              infowindow.open(map, marker);
                            document.getElementById('autocomplete').value = results[0].formatted_address;

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

        </script>



for语句中的异步回调=recursiontry for let i in datainstead@RemisaYousefvand不,递归与异步无关,回调也与loopshow无关。你是为了防止递归吗?@feaseyweis没有递归,所以没有什么可以防止的。。。尝试使用let而不是var的最简单解决方案。。。您遇到的问题是,在异步代码调用回调后,我将不会是您所期望的那样-但是,使用let,它将完全是您所期望的,因为letI的块范围尝试了这一点。由于getDistanceMatrix异步运行,在代码完成之前不会返回结果,因此kms在分配kms值后仍然显示为未定义的检查回调\u calcDistance函数调用。我可以通过回调函数Callback\u calcDistancekms访问kms,并通过console进行检查。logdistanceResult+kms;但是不能从回调中得到它。Callback\u calcDistancekms函数调用了引用参数函数ref\u Callback\u calcDistancekms右,我认为是另一种方式??Callback_calcDistancekms通过ref_Callback_calcDistancekms传递