JavaScript - callback - waiting for multiple funct

2019-08-29 01:27发布

I count the shortest path to the destination point from many different origin points with google maps api. I decided to do it this way : (count for each pair of points than save results to array and than check at the end which is best). But i have problem with callback - because as comments says array is always zero - because this code is performed before all requests to count the route length.

function foo(){
var directionsService = new google.maps.DirectionsService();
var destination = new google.maps.LatLng(x,y);
var arrayOfRes= [];

for(var index in originPoints){
    var request = {
        origin:originPoints[index].marker.position,
        destination:destination,
        travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function(result, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                var res = {};
                res.length = result.routes[0].legs[0].distance.value;
                res.index = index;
                res.result = result;
                arrayOfRes.push(res);
            }
     });
}
  //here arrayOfRes.length is always 0
if(arrayOfRes.length>1)
{
    var bestResult = arrayOfRes[0];

    for(var i = 1; i < arrayOfRes.length; i++)
    {
        if(bestResult.length > arrayOfRes[i])
            bestResult = arrayOfRes[i];
    }

    console.log("Best is" + bestResult.length);
}
else if(arrayOfRes.length ==1)
{
    var bestResult = arrayOfRes[0];
}
 }

How to write function with callback so that it wait until all requessts are ended?

1条回答
Luminary・发光体
2楼-- · 2019-08-29 01:56

Google requests like this are asynchronous so you have to write asynchronous code which means ONLY working with the returned data from the callback.

In your callback function that returns a route, you need to check if this is the answer to the last request. If so, then your array has all the results and you can then process the array.

Assuming that originPoints is an array, you could do it like this:

var arrayOfRes = [];
for (var index = 0; index < originPoints.length; ++index) {
    var request = {
        origin:originPoints[index].marker.position,
        destination:destination,
        travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function(result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            var res = {};
            res.length = result.routes[0].legs[0].distance.value;
            res.index = index;
            res.result = result;
            arrayOfRes.push(res);

            // check if all data has arrived
            if (arrayOfRes.length === originPoints.length) {
                // put code here to process arrayOfRes
            }
        }
    });
}

Note: javascript does not have the ability to make your code wait for all the requests to be done and then continue - thus you have to use an asynchronous programming style with the flow of code continuing from the callback.

Note: because directionsService.route is an asynchronous call, it will call its callback sometime in the future. In the meantime, you JS will continue to execute. That means that the code that comes right after this block of code will execute BEFORE the ajax calls have completed and before arrayOfRes is populated. As such, the ONLY place you can safely use the arrayOfRes data is in the callback itself or in a function that you call from the callback.

查看更多
登录 后发表回答