2016-10-26 34 views
1

我有2个API调用。Angular nested Promise显示错误

第二个API调用取决于返回的属性ID,以便进行第二次API调用以检查这些属性中的每个属性是否都有停放。

如果是这样,那么我将该属性的详细信息添加到一个对象并将该对象推送到一个数组中。

第二个API调用嵌套在第一个API中。在遍历所有属性后,我检查数组长度是否大于0,如果是,则可以在页面中显示返回的属性,否则显示错误。

问题是,即使有停放属性返回,执行else语句或错误函数,以及在页面上显示属性。

有没有办法在检查我的数组是否大于0之前完成嵌套Promise?

这里是我的代码:

$scope.viewPropertyList = function(latlong) { 
 
    $scope.locationError = false; 
 
    var latlongArray = latlog.split('::'); 
 
    var searchLat_scope = latlongArray[0]; 
 
    var searchLon_scope = latlongArray[1]; 
 

 
    if (searchLat_scope && searchLon_scope) { 
 
     var data = Property.getAllProperties({ 
 
      dest: 'property', 
 
      apikey: API_KEY, 
 
      lat: encodeURIComponent(searchLat_scope), 
 
      limit: 10, 
 
      lon: encodeURIComponent(searchLon_scope) 
 
     }).$promise.then(function(success) { 
 
      var propertyMarkers = []; 
 
      $scope.dbMarkers = 0; 
 
      for (var i = 0, l = success.property.length; i < l; i++) { 
 
       (function(i) { 
 
        Property.getProperty({ 
 
         dest: 'property', 
 
         propertyId: success.property[i].name, 
 
         apikey: API_KEY 
 
        }).$promise.then(function(propertyData) { 
 

 
         for (var j = 0, k = propertyData.services.length; j < k; j++) { 
 
          if (propertyData.services[j].name === "parking") { 
 
           var obj = { 
 
            "propertyName": success.property[i].propertyName, 
 
            "telephone": success.property[i].telephone, 
 
            "postcode": success.property[i].address.postcode, 
 
            "city": success.property[i].address.city, 
 
            "county": success.property[i].address.county, 
 
            "addressLine1": success.property[i].address.addressLine1 
 
           }; 
 
           propertyMarkers.push(obj); 
 
          } 
 

 
         } 
 

 
         if (propertyMarkers.length != 0) { 
 
          $scope.dbMarkers = propertyMarkers; 
 
          $scope.selectedLat = searchLat_scope; 
 
          $scope.selectedlog = searchLon_scope; 
 

 
         } else { 
 
          $scope.locationErr = true; 
 
          $scope.errorMsg = "No properties found"; 
 
         } 
 

 
        }); 
 

 
       })(i); 
 
      } 
 
     }, function(error) { 
 
      $scope.locationErr = true; 
 
      $scope.errorMsg = "Something went wrong, please try again"; 
 
     }); 
 
    } 
 
}

回答

0

两两件事:

  • 没有试图聚集在一个循环中生成的多个承诺。
  • if (propertyMarkers.length > 0) {...} else {...}嵌套太深。

辅修:

  • 内部循环能够尽快 '停车场' 中找到突破。如果它继续并且发现进一步“停车”,则将创建重复的标记。
$scope.viewPropertyList = function(latlong) { 
    $scope.locationError = false; 
    var latlongArray = latlog.split('::'); 
    var searchLat_scope = latlongArray[0]; 
    var searchLon_scope = latlongArray[1]; 

    if (searchLat_scope && searchLon_scope) { 
     Property.getAllProperties({ 
      dest: 'property', 
      apikey: API_KEY, 
      limit: 10, 
      lat: encodeURIComponent(searchLat_scope), 
      lon: encodeURIComponent(searchLon_scope) 
     }).$promise.then(function(success) { 
      var propertyMarkers = []; 
      $scope.dbMarkers = 0; 

      // create an array of promises by mapping the array `success.property`. 
      var promises = success.property.map(function(prop) { 
       return Property.getProperty({ 
        dest: 'property', 
        propertyId: prop.name, 
        apikey: API_KEY 
       }).$promise.then(function(propertyData) { 
        for (var j=0, k=propertyData.services.length; j<k; j++) { 
         if (propertyData.services[j].name === 'parking') { 
          propertyMarkers.push({ 
           'propertyName': prop.propertyName, 
           'telephone': prop.telephone, 
           'postcode': prop.address.postcode, 
           'city': prop.address.city, 
           'county': prop.address.county, 
           'addressLine1': prop.address.addressLine1 
          }); 
          break; // 'parking' is found - no point iterating further 
         } 
        } 
       }); 
      }); 

      /* ******** */ 
      // Aggregate `promises` 
      $q.all(promises).then(function() { 
       // This block is now un-nested from its original position, 
       // and will execute when all `promises` have resolved. 
       if (propertyMarkers.length > 0) { 
        $scope.dbMarkers = propertyMarkers; 
        $scope.selectedLat = searchLat_scope; 
        $scope.selectedlog = searchLon_scope; 
       } else { 
        $scope.locationErr = true; 
        $scope.errorMsg = 'No parking found'; 
       } 
      }); 
      /* ******** */ 

     }).catch(function(error) { 
      $scope.locationErr = true; 
      $scope.errorMsg = 'Something went wrong, please try again'; 
     }); 
    } else { 
     $scope.locationErr = true; 
     $scope.errorMsg = 'Problem with lat/lng data'; 
    } 
} 

注:

  • 使得外迭代现在编码为success.property.map(),它返回promises和避免了对IIFE的需要。
  • 添加了额外的错误处理
+1

固定它。非常感谢您对@ roamer-1888的帮助 – Harry

0

如果我得到你的问题吧,你想要的所有success.property承诺Property.getProperty才去的成功的功能检查propertyMarkers长度都解决了。

在这种情况下,您需要$q.all来解决您的所有Property.getProperty承诺。

在你for (var i = 0, l = success.property.length; i < l; i++) {追加所有承诺到一个数组

Property.getProperty({ 
        dest: 'property', 
        propertyId: success.property[i].name, 
        apikey: API_KEY 
       }) 

然后使用$q.all(arrPromises).then(function(propertyData) {做以下检查。

还有一件值得一提的,承诺链接可以通过$promise.then(successFn, failFn).then(successFn, failFn).then...轻松实现。每当您致电then()时,都会创造出另一个承诺,让您链接到下一个承诺并将价值传递给下一个承诺。