for循环将元素成功添加到数组,但之后返回空数组

时间:2016-03-13 18:07:18

标签: javascript arrays angularjs for-loop

所以这段代码成功运行并将元素添加到数组中,通过将它们记录到控制台来确认,但是当我返回数组时,它返回为空。整个上午,我一直在撞墙。

details.getDetails = function(idSet, pageNum) {
      var page = idSet[pageNum],
          placeDetails = [],
          i;

      for(i=0; i<page.length; i++){
        ngGPlacesAPI.placeDetails({placeId: page[i]})
          .then(function(data){
            response = data;
            placeDetails.push(response);
            console.log(placeDetails) //This shows the loop running and the array being populated
          })
      }
      return placeDetails;
      console.log(placeDetails) //This returns empty array 
    };

我确实认为这个问题可能与Rayon提到的异步数据有关,我试图回复一个承诺,但我不确定我做得对。这是我试过的代码。

.factory('details', function(ngGPlacesAPI, $q){
    var response,
        details = {};

 details.getDetails = function(idSet, pageNum) {
      var page = idSet[pageNum],
          deferred = $q.defer,
          placeDetails = [],
          i;

      for(i=0; i<page.length; i++){
        ngGPlacesAPI.placeDetails({placeId: page[i]})
          .then(function(data){
            response = data;
            placeDetails.push(response);
          })
      }
      deferred.resolve(placeDetails);
      console.log(deferred.promise);
      return deferred.promise;
    };

    // Return Details Object
    return details;
  });

1 个答案:

答案 0 :(得分:1)

这里的问题是.placeDetails会立即返回,因此在您实际检索某些数据之前,for循环已经完成了很长时间。这就是为什么在这里使用Promise并不能真正帮助你,因为几乎可以立即调用解决方案。

我建议在解决你的承诺之前,先调查$ q.all等待所有对placeDetails的调用完成。

像这样(未经测试的)代码应该适合你。它可能需要一些改变,但它应该给你一个想法。

details.getDetails = function(idSet, pageNum) {
      var page = idSet[pageNum],
          placeDetails = [],
          mainDeferred = $q.defer(),
          promises = [];

      for(var i=0; i<page.length; i++){
        var deferred = $q.defer();
        ngGPlacesAPI.placeDetails({placeId: page[i]})
          .then(function(data){
            placeDetails.push(data);
            deferred.resolve();
          });
        promises.push(deferred.promise);
      }
    $q.all(promises).then(function() {
       mainDeferred.resolve(placeDetails); 
    });
    return mainDeferred;
  });