$ q.all()没有在then子句之前运行所有promise

时间:2017-01-20 06:55:17

标签: angularjs angular-promise angular-http

我需要完成所有的ajax调用才能启用按钮,但是在启用按钮之前我没有完成所有的承诺。

我的所有ajax都有这段代码:

var temp = {};
for (var i=0; i<serie_chart.length; i++) {
    if(!temp[serie_chart[i].name]) {
     temp[serie_chart[i].name]=[];
    }
    temp[serie_chart[i].name].push(serie_chart[i].data);
}
serie_chart = [];
for (var key in temp) {
    serie_chart.push({'name': key, 'data': temp[key]})
}

每个加载函数都是$ http.get,如下所示:

                $q.all([
                    $scope.load_ocupacoes(),
                    $scope.load_tipos_pisos(),
                    $scope.load_tipos(),
                    $scope.load_caracteristicas(),
                    $scope.load_amenidades(),
                    $scope.load_subtipos(true, 'incluir')
                ]).then(function() {
                    console.log('loading complete !!!');
                    $scope.theglyphicon = 'fa fa-check fa-fw';
                    $scope.isDisabledButton = false;
                });

我也尝试过这种方式:

    $scope.load_ocupacoes = function() {

        $http.get(url_api_status_ocupacao)
            .success(function(response) {
                console.log(response);
                $scope.status_ocupacoes = response;
            })
            .error(function(response) {
                console.log(response);
                ngToast.create({
                    className: 'danger', 
                    content: 'Não foi possível recuperar a lista.'
                });
            });
    };

而这......但同样的问题:

        $scope.load_ocupacoes = function() 
{$resource(url_api_status_ocupacao).query().$promise.then(function(response) {
                console.log(response);
                $scope.status_ocupacoes = response;
            });
    };

但是,我收到的消息是“加载完整!!!&#39;在所有装载结束之前。

这种方法有问题吗?

4 个答案:

答案 0 :(得分:2)

可能会有更多错误,但基本的误解是$q.all接受了承诺,并且所有函数都返回undefined(因为它们没有return语句) - 所以你的$q.all得到六个未定义,而不是六个承诺。 AFAIK,$http.get默认返回一个promise,所以修复它的一种方法是在$http.get前面的每个函数中添加return语句,如下所示:

   $scope.load_ocupacoes = function() {   
        return $http.get(url_api_status_ocupacao)
            .then(function(response) {

            });
    };

答案 1 :(得分:0)

我猜$ q.all接受承诺。

这必须适用于所有其他相关方法。

$scope.load_ocupacoes = function() {   
        $http.get(url_api_status_ocupacao)
            // use then instead success
            .then(function(response) {
                 // return raw promise instead actual value
                return response;
            }, console.log('error));
    };

答案 2 :(得分:0)

$ q.all需要一系列承诺,但你提供的函数既不会返回任何承诺。

你可以这样做:

    $q.all([
$http.get(url_api_status_ocupacao),
$http.get(url_api1),
$http.get(url_api2)
]).then(function() {
 ......
                    });

答案 3 :(得分:0)

我用这种方法解决了我的问题:

var promises = [appFactory.recuperarLista(url_api_status_ocupacao),
                appFactory.recuperarLista(url_api_tipos_pisos),
                appFactory.recuperarLista(url_api_caracteristicas),
                appFactory.recuperarLista(url_api_amenidades)
                ];
$q.all(promises).then(function (responses) {
    $scope.status_ocupacoes = responses[0];
    $scope.tipos_pisos = responses[1];
    $scope.caracteristicas = responses[2];
    $scope.amenidades = responses[3];
}).then(function() {
    console.log('All Loading completed !!!');
});

我做了一个回报承诺的工厂:

angular.module('starter.services', ['datatables'])
.factory('appFactory', function($http, $q) {

 return {
       recuperarLista: function(url) {

            var deferred = $q.defer();

            $http({ method: "GET", url: url })
                .success(function (data, status, headers, config) {
                    deferred.resolve(data);
                }).error(function (data, status, headers, config) {
                deferred.reject(status);
            });

            console.log('loading for ' + url + ' was completed !!!');

            return deferred.promise;
        }
    };
});

现在我得到这个控制台输出:

loading for api/loadliststatusocupacoes was completed !!! 
services.js:171 
loading for api/loadlisttipospisos was completed !!!
 services.js:171 
loading for api/loadlistcaracteristicas was completed !!!
 services.js:171 
loading for api/loadlistamenidades was completed !!! 
services.js:171
All Loading completed !!! 
imovel-controller.js:690