Angular Promise - $ q.all没有返回结果并多次调用Post方法

时间:2016-08-18 09:27:58

标签: angularjs promise http-post angular-promise q

尝试调用Post方法然后根据结果我将多次调用相同的Post方法并使用$ q.all返回结果。

我的Post方法是:

getData: function (params, callback) {
                $http.post('service/myService', params)
                    .success(function (data) {
                        callback(null, data);
                    }).error(function (error) {
                        callback(error);
                    });
            }

我在下面的函数中调用它,这个函数是递归的,所以如果它包含nextUrl我做同样的事情,直到paging没有对象:

var result = [];
var promises = [];
var checkForPaging = function (nextUrl, service, $q) {
    var deferred = $q.defer();
    var criteria = {
        url: url
    }
    var promise = service.getData(criteria, function (error, data) {
        if (data.statusCode == 200) {
            for (var i = 0; i < data.body.items.length; i++) {
                result.push(data.body.items[i]);
            }
            if (data.body.paging != null && data.body.paging.next != null) {
                checkForPaging(data.body.paging.next.url, service, $q);
            } else{
               deferred.resolve(result);
            }
        }
    });

    promises.push(promise);
    $q.all(promises)
    return deferred.promise;
}

然后从下面调用此函数,并希望在所有调用完成后返回result

checkForPaging(data.body.paging.next.url, myService, $q).then(function (data) {
        console.log(data)
    });

我遇到的问题是它永远不会遇到上面的回调函数:console.log(data)。但我可以看到它多次调用Post方法。

如果我像下面那样解决它,那么我可以在第一次Post之后看到它正在点击上面的回调:

$q.all(promises).then(function (results) {
           deferred.resolve(result);
       }, function (errors) {
           deferred.reject(errors);            
       });

我做得对吗?如何获得结果并多次调用Post方法?

如果不清楚或有任何问题,请告诉我们!

2 个答案:

答案 0 :(得分:1)

尝试使用正确的承诺链接这样的事情:

var result = [];

var checkForPaging = function(nextUrl, service) {
    var criteria = {
        url: url
    }
    return service.getData(criteria, function(error, data) {
        if (data.statusCode == 200) {
            for (var i = 0; i < data.body.items.length; i++) {
                result.push(data.body.items[i]);
            }
            if (data.body.paging != null && data.body.paging.next != null) {
                return checkForPaging(data.body.paging.next.url, service);
            } else {
                return result;
            }
        }
    });
}

checkForPaging(data.body.paging.next.url, myService).then(function(data) {
    console.log(data)
});

getData:

getData: function(params) {
    return $http.post('service/myService', params)
        .then(function(response) {
            return response.data;
        });
}

答案 1 :(得分:0)

这是解决方案:https://plnkr.co/edit/HqkFNo?p=preview我重写了一点逻辑。 你可以抓住主要想法。

UPDATE添加了无证解决方案

1)您的服务应该只返回承诺:

this.getData = function(url, params){
    return $http.post(url, params); //You're just returning promise
}

2)你不需要$ q.all,你可以使用单一承诺:

var result = [];

var deferred;

var checkForPaging = function (url) {

    if(!deferred){
        deferred = $q.defer();
    }

    //resolvind service promise
    newService.getData(url).then(
        //if ok - 200
        function(response){
            for (var i = 0; i < data.body.items.length; i++) {
                result.push(data.body.items[i]);
            }

            if (data.body.paging != null && data.body.paging.next != null){
            {
                return checkForPaging(data.body.paging.next.url);
            } else{
               deferred.resolve(result);
            }
        },
        //handle errors here
        function(error) {

        }
    );

    return deferred.promise;
}

3)你应该这样称呼它:

checkForPaging('url').then(function(data){
    //here will be resolved promise
    console.log(data);
});