jayt.dev
jayt.dev

Reputation: 1015

Handling many asynchronous requests

I have an array of 1000 LatLngBounds objects var recBounds = []; For each one of them I would like to create and display a rectangle, get the elevation of the rectangle center from Google Elevation Service and color the rectangle depending on the elevation value.

function getElevation() { 
        elevs = [];
        for (i = 0; i < recBounds.length; i++) {
            var elevation;
            var locations = [];
            locations.push(recBounds[i].getCenter());
            var positionalRequest = { 'locations': locations }
            var elevator = new google.maps.ElevationService();
            elevator.getElevationForLocations(positionalRequest, 
            function (results, status) {
                if (status == google.maps.ElevationStatus.OK) {
                    if (results[0]) {
                        elevation = results[0].elevation;
                        elevs.push(elevation);
                        if (recBounds.length == elevs.length) {
                            createRect();
                        }
                    }
                }
            })
        }
    }

(I am iterating through each LatLngBounds object in the array instead of passing the entire array to the asynchronous function because Elevation Service only accepts about 300 locations. )

The problem is that the Elevation service seems to return the elevation results not in the same order that correspond to recBounds array. I guess that the elevation of some cached locations is returned immediately and is stored at the top of elevs array. So when I try to display the rectangles for example recBounds[4] does not correspond to the elevation of elevs[4] .

I am trying to pass the LatLngBounds as a parameter to the getElevationForLocations() function and use it later to create a new array with matched bounds and elevations but with no luck. Any ideas how to implement this?

Upvotes: 1

Views: 180

Answers (1)

David
David

Reputation: 3763

If you know how many results you will have ahead of time then instead of pushing onto an array have each function put it's results into a specific point in the results array.

eg:

function getElevation() {
    var elevs = [];
    var locations = [];

    for (i = 0; i < recBounds.length; i++) {
        var elevation;

        locations[i] = recBounds[i].getCenter();

        var positionalRequest = { 'locations': locations };

        var elevator = new google.maps.ElevationService();

        elevator.getElevationForLocations(positionalRequest, (function (index) {
            return function (results, status) {
                if (status == google.maps.ElevationStatus.OK) {
                    if (results[0]) {
                        elevation = results[0].elevation;
                        elevs[index] = elevation;
                        if (recBounds.length == elevs.length) {
                            createRect();
                        }
                    }
                }
            }
        })(i));
    }
}

I haven't test run the code but in theory it should work or at least give you a direction to look into. The results from the async call are wrapped in another function to allow it access to it's index in the loop.

Hopefull this is of some help to you.

Upvotes: 2

Related Questions