如何等待多个 ngResource $resource 查询来解决

How to Wait for Multiple ngResource $resource Queries to Resolve

我的控制器中有这些 ngResource 查询:

Ages.query(function(ages){
    $scope.ages = ages;
});

Skinissues.query(function(skinissues){
    $scope.skinissues = skinissues;
});

Skintypes.query(function(skintypes){
    $scope.skintypes = skintypes;
});

Activities.query(function(activities){
    $scope.activities = activities; 
});

在同一控制器中的 findOne 函数中:

$scope.findOne = function() {

    Products.get({
        productId: $routeParams.productId
    }, function(product) {
        for (var i = 0; i < product.ages.length; i ++){
            for (var j = 0; j < $scope.ages.length; j ++){
                if (product.ages[i].id == $scope.ages[j].id){
                    $scope.ages[j]['ticked'] = true;
                }
            }
        }
        for (var i = 0; i < product.activities.length; i ++){
            for (var j = 0; j < $scope.activities.length; j ++){
                if (product.activities[i].id == $scope.activities[j].id){
                    $scope.activities[i]['ticked'] = true;
                }
            }
        }
        for (var i = 0; i < product.skintypes.length; i ++){
            for (var j = 0; j < $scope.skintypes.length; j ++){
                if (product.skintypes[i].id == $scope.skintypes[j].id){
                    $scope.skintypes[i]['ticked'] = true;
                }
            }
        }
        for (var i = 0; i < product.skinissues.length; i ++){
            for (var j = 0; j < $scope.skinissues.length; j ++){
                if (product.skinissues[i].id == $scope.skinissues[j].id){
                    $scope.skinissues[i]['ticked'] = true;
                }
            }
        }
        for (var i = 0; i < $scope.parents.length; i ++){
            if ($scope.parents[i].id == product.parent.id){
                $scope.parents[i]['ticked'] = true;
            }
        }
        console.log('Products', product);
        $scope.product = product;
    });

};

此代码有时有效,有时无效,因为在 findOne 函数中,有时 $scope.ages $scope.skinissues $scope.skintypes$scope.activities不明确的。

发生这种情况是因为他们的查询尚未完成。

我该怎么做才能解决这个问题?

请帮忙。谢谢。

谢谢,我已经通过使用 setInterval 检查是否定义了所有变量来提供这项服务。

angular.module('mean.variables')
.factory('Variables', ['$q', 'Products', 'Ages', 'Activities', 'Skinissues', 'Skintypes', '_', function($q, Products, Ages, Activities, Skinissues, Skintypes, _){

    return {
        get: function(){
            var variables = {};
            var defer = $q.defer();
            Ages.query(function(res){
                variables.ages = res;
            });

            Skinissues.query(function(res){
                variables.skinissues = res;
            });

            Skintypes.query(function(res){
                variables.skintypes = res;
            });

            Activities.query(function(res){
                variables.activities = res; 
            });

            Products.query(function(res){
                variables.parents = res;
            });

            var timer = setInterval(function(){
                if (variables.ages && variables.activities && variables.skinissues && variables.skintypes && variables.parents){
                    defer.resolve(variables);
                    clearInterval(timer);
                }
            }, 50);

            return defer.promise;

        }
    }

}])

使用 $q.all 解决 $resource 承诺。

angular.module('mean.variables')
.factory('Variables', function($q, Products, Ages, Activities, Skinissues, Skintypes, _){

    return {
        get: function(){
            var promiseHash = {};

            promiseHash.ages = Ages.query().$promise;
            promiseHash.skinissues = Skinissues.query().$promise;
            promiseHash.skintypes = Skintypes.query().$promise;
            promiseHash.activities = Activities.query().$promise;
            promiseHash.parents = Products.query().$promise;

            return $q.all(promiseHash);

        }
    }
});

上面的示例函数 returns 一个承诺,它要么 成功地 解析为查询对象的散列,要么解析 拒绝 使用第一个被拒绝的响应对象。

使用 $q.all() 而不是 $q.defer 的优点是承诺链不会被破坏,并且会为工厂的客户保留错误响应。

来自文档:

The Resource instances and collections have these additional properties:

  • $promise: the promise of the original server interaction that created this instance or collection.

On success, the promise is resolved with the same resource instance or collection object, updated with data from server. This makes it easy to use in resolve section of $routeProvider.when() to defer view rendering until the resource(s) are loaded.

On failure, the promise is rejected with the http response object, without the resource property.

If an interceptor object was provided, the promise will instead be resolved with the value returned by the interceptor.

--AngularJS ngResource API Reference


all(promises);

Combines multiple promises into a single promise that is resolved when all of the input promises are resolved.

Parameters

An array or hash of promises.

Returns

Returns a single promise that will be resolved with an array/hash of values, each value corresponding to the promise at the same index/key in the promises array/hash. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value.

--AngularJS $q Service API Reference -- $q.all