Angular nested Promise显示错误

时间:2016-10-26 08:36:28

标签: angularjs api http nested promise

我有2个API调用。

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

如果是,那么我将该属性的细节添加到对象并将对象推入数组。

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

问题是即使在停车时返回属性,执行else语句或错误功能,以及在页面上显示属性。

在检查我的Array是否超过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";
        });
    }
}
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

如果我的问题正确,您希望<div class="blm"> blm </div> <div class="blm2"> blm2 </div>的所有Property.getProperty承诺得到解决,然后再转到成功函数检查success.property长度。

在这种情况下,您需要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...都会创建另一个承诺,允许您链接到下一个承诺并将值传递给下一个承诺。

答案 1 :(得分:0)

两件主要的事情:

  • 没有尝试聚合循环中生成的多个promise。
  • if (propertyMarkers.length > 0) {...} else {...}嵌套太深。

轻微:

  • 内部迭代可以在“停车”时立即中断。找到了。如果它继续并进一步停车&#39;找到了,然后会创建重复的标记。
$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。
  • 添加了额外的错误处理