For 循环成功地将元素添加到数组中,但在之后返回空数组

For loop adds elements to array succesfully but returns empty array after

本文关键字:数组 之后 返回 成功 循环 添加 元素 For      更新时间:2023-09-26

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

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;
  });

这里的问题是 .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;
  });