MY ANSWER BELOW HAS A WORKING CODE EXAMPLE AND AN EXPLANATION
I am trying to get my head around asynchronous programming by creating a Traveling Salesperson algorithm with the help of the Google maps API.
Here is how it should work:
- We have a list of address strings
addresses
- For every combination of address [i] and [j] we calculate the distance, using google
directionsService and we store this in a Javascript object (
distanceTable
). - The tspSolver should run after we have all the distances (not implemented yet).
My naive code is below. As you can see there are several issues, all of which have to do with callbacks:
I pass directionResults
as a callback to the directionsService. It correctly calculates the distance, but since I am no longer inside the loop to construct the distanceTable, I cannot store the result correctly. I commented out the section which should store it, but that obviously only works inside the loop.
I pass my tspSolver
as a callback for allDistances
. However I notice that it gets executed before the distances are calculated by directionResults
. My guess is that I have to do some form of nesting of callbacks?
Who can help me make sense of this.
gMap.directionsService = new google.maps.DirectionsService();
var addresses = ['Dam, Amsterdam','Spui, Amsterdam','Middenweg, Amsterdam'];
var distanceTable = {};
//all combinations of addresses with distances, for use in TSP algorithm
//{
// addressA {
// addressB: 2000
// addressC: 2500
// }
// addressB {
// addressC: 1800
// }
function tspSolver(distanceTable) {
console.log('Distances are there, now for some clever TSP algorithm')
//this should only be executed after the distances are returned.
}
function allDistances(addresses, callback) {
for(var i=0; i<addresses.length; ++i) {
distanceTable[addresses[i]] = {};
for(var j=i+1; j<addresses.length; ++j) {
// Compose request for every pair of addresses (one way)
var request = {
origin: addresses[i],
destination: addresses[j],
travelMode: 'DRIVING'
};
console.log(request);
gMap.directionsService.route(request, directionResults);
}
}
callback(distanceTable)
}
function directionResults(result, status) {
console.log("Receiving request for route");
console.log(result);
if (status == google.maps.DirectionsStatus.OK) {
var totalDistance = 0;
var legs = result.routes[0].legs;
for(var i=0; i<legs.length; ++i) {
totalDistance += legs[i].distance.value;
}
console.log(totalDistance);
// I really want to add it to the distanceTable...
//distanceTable[addresses[i]][addresses[j]] = totalDistance;
}
}
//call function to start solving
function executeTSP() {
allDistances(addresses, tspSolver);
}