I'm having trouble wrapping my head around promises. I'm using the Google Earth API to do a 'tour' of addresses. A tour is just an animation that lasts about a minute, and when one completes, the next should start.
Here's my function that does a tour:
var tourAddress = function (address) {
return tourService.getLatLong(address).then(function (coords) {
return tourService.getKmlForCoords(coords).then(function (kml) {
_ge.getTourPlayer().setTour(kml);
_ge.getTourPlayer().play();
var counter = 0;
var d = $q.defer();
var waitForTour = function () {
if (counter < _ge.getTourPlayer().getDuration()) {
++counter;
setTimeout(waitForTour, 1000);
} else {
d.resolve();
}
};
waitForTour();
return d.promise;
});
});
}
This seems to work pretty well. It starts the animation and returns a promise that resolves when the animation is complete. Now I have an array of addresses, and I want to do a tour foreach of them:
$scope.addresses.forEach(function (item) {
tourAddress(item.address).then(function(){
$log.log(item.address + " complete");
});
});
When i do this, they all execute at the same time (Google Earth does the animation for the last address) and they all complete at the same time. How do I chain these to fire after the previous one completes?
UPDATE
I used @phtrivier's great help to achieve it:
$scope.addresses.reduce(function (curr,next) {
return curr.then(function(){
return tourAddress(next.address)
});
}, Promise.resolve()).then(function(){
$log.log('all complete');
});
reduce
is what I'm looking for. I'll see if i can get it working – Gunstock