title: AngularJS : chaining promises over forEach loop
body: <p>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.  </p>
  
  <p>Here's my function that does a tour:</p>
  
  <pre><code>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 &lt; _ge.getTourPlayer().getDuration()) {
                          ++counter;
                          setTimeout(waitForTour, 1000);
                      } else {
                          d.resolve();
                      }
                  };
  
                  waitForTour();
  
                  return d.promise;
              });
          });
      }
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>$scope.addresses.forEach(function (item) {
        tourAddress(item.address).then(function(){
            $log.log(item.address + " complete");
         });
   });
  </code></pre>
  
  <p>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?  </p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I used @phtrivier's great help to achieve it:</p>
  
  <pre><code> $scope.addresses.reduce(function (curr,next) {
        return curr.then(function(){
              return tourAddress(next.address)
        });
    }, Promise.resolve()).then(function(){
        $log.log('all complete');
    });
  </code></pre>