最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - Wait for Loop to finish before passing the value in javascript (also google maps). - Stack Overflow

programmeradmin0浏览0评论

I don't use javascript much so I am not that familiar with callbacks and responses. I am using google maps to map out distance between point A and point X,Y,Z. The catch is, I want to use javascript to determine which of the points X,Y,Z is closest to A and them map out the directions between them.

My code is working. I can figure out the shortest distance out all the 3 destinations but I am stuck with this stupid for look.

You see, Google uses async callbacks to provide data to the browser and if I run a for loop to check all the 3 destinations 1 by 1, I get incorrect results.

Here is the code:

var maxDistance = 99999999999;
var destn;
for (var i = 0; i < locations.length; i++) {
  var thisDistance = 0;
  var start = origin;
  var end = locations[i];
  var request = {
    origin: start,
    destination: end,
    travelMode: google.maps.DirectionsTravelMode.DRIVING
  };
  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      thisDistance = response.routes[0].legs[0].distance.value;
      if (thisDistance < maxDistance) {
        destn = response.routes[0].legs[0].end_address;
        maxDistance = thisDistance;
      }
    } else {
      document.getElementById("addressNotFound").style.display = 'block';
    }
  });
}
calcShortestRoute(origin, destn);

So obviously when I call this function, the value of destn es up as undefined since the loop finishes and the google handler hasnt received the data yet. If I call the function 1 more time, I get the destn value that was received from the previous callback (which gave undefined before).

Someone please tell me how I can fix this.

I don't use javascript much so I am not that familiar with callbacks and responses. I am using google maps to map out distance between point A and point X,Y,Z. The catch is, I want to use javascript to determine which of the points X,Y,Z is closest to A and them map out the directions between them.

My code is working. I can figure out the shortest distance out all the 3 destinations but I am stuck with this stupid for look.

You see, Google uses async callbacks to provide data to the browser and if I run a for loop to check all the 3 destinations 1 by 1, I get incorrect results.

Here is the code:

var maxDistance = 99999999999;
var destn;
for (var i = 0; i < locations.length; i++) {
  var thisDistance = 0;
  var start = origin;
  var end = locations[i];
  var request = {
    origin: start,
    destination: end,
    travelMode: google.maps.DirectionsTravelMode.DRIVING
  };
  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      thisDistance = response.routes[0].legs[0].distance.value;
      if (thisDistance < maxDistance) {
        destn = response.routes[0].legs[0].end_address;
        maxDistance = thisDistance;
      }
    } else {
      document.getElementById("addressNotFound").style.display = 'block';
    }
  });
}
calcShortestRoute(origin, destn);

So obviously when I call this function, the value of destn es up as undefined since the loop finishes and the google handler hasnt received the data yet. If I call the function 1 more time, I get the destn value that was received from the previous callback (which gave undefined before).

Someone please tell me how I can fix this.

Share Improve this question edited Mar 12, 2017 at 19:01 Baumannzone 7802 gold badges20 silver badges38 bronze badges asked Apr 13, 2011 at 18:10 Rohit ChopraRohit Chopra 2,8214 gold badges30 silver badges33 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

You need to wait until all three Google responses have been returned. A simple solution is: move you distance calculation function call into the anonymous function at the end, and then calc the distances only if all responses have returned:

        // global count variable
        var callbackCount = 0;

        for (var i = 0; i<locations.length; i++) {
            var thisDistance=0;
            var start = origin;
            var end = locations[i];
            var request = {
                origin:start,
                destination:end,
                travelMode: google.maps.DirectionsTravelMode.DRIVING
            };
            directionsService.route(request, function(response, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                    thisDistance = response.routes[0].legs[0].distance.value;
                    if (thisDistance < maxDistance) {
                        destn = response.routes[0].legs[0].end_address;
                        maxDistance = thisDistance;
                    }                            
                }
                else {
                    document.getElementById("addressNotFound").style.display = 'block';
                }

                // move this to here, and pass in number of locations
                calcShortestRoute(origin, destn, locations.length);
            });



        }

then calcShortestRoute looks like:

function calcShortestRoute(origin, destn, locationCount) {

  // increment callback count
  callbackCount++;

  if (callbackCount == locationCount) {   // all responses have returned


     // do your distance checking      
     ....

   }
}

You won't have a value in destn when you exit the for loop because it is set asynchronously after you receive your results from directionsService.route(). Instead, you'll need to keep track of how many requests have returned, and call your function from within the response callback after you've received all of the responses:

... // your code
var responseCount = 0;
for (var i = 0; i < locations.length; i++) {
    ... // your code
    directionsService.route(request, function(response, status) {
        ... // your code
        if (++responseCount == locations.length) {
            calcShortestRoute(origin, destn);
        }
    });
}

Edit: I re-read your question and think I understand better what your code is doing. This answer should be more accurate (and more concise to boot!).

发布评论

评论列表(0)

  1. 暂无评论