Angular 多个http完成时的回调

Angular callback when multiple http are done

如何在 angularjs 中为多个 http 创建 1 个回调函数。我的代码:

for (var i = 0; i < docs.length; i++) {
    this.base64(docs[i], function(base64Img){
        $http.post(urls.BASE + '/store',{doc:base64Img}).then(
            function(result) {
                console.log(result);
            }
         );
     });
 }

 mycallback.call(); <-- this should be done when all my http.post above are done.

好的,所以我为此创建了一个 HttpInterceptor 服务,因此每次请求启动时,它都会检查在某个时间限制内是否还有更多请求,然后在所有这些请求都响应后它会广播 "all requests done".

为此,我将这样的拦截器嵌入到 App.js

.config(function ($httpProvider) {
    $httpProvider.interceptors.push('httpInterceptor');
})

我的服务基本上是这样的,有一个变量 numloadings,它对请求进行计数,当有响应时,它会在响应达到 0 时对请求进行计数,所有请求都通过

.factory('httpInterceptor', ['$q', '$rootScope', '$filter', function ($q, $rootScope, $filter) {
var canceller = $q.defer();
var numLoadings = 0;
var serialRequests = false;
var timeO;
var time1;
var Cntr1 = 0;
var Cntr2 = 0;
var currentReqUrl;
$rootScope.broadcast = true;
var loadingbar = { loading: "<progress value='?' max='10'></progress>" };
var loadingspinner = { loading: '<ion-spinner icon="crescent"></ion-spinner>' };

return {

    request: function (config) {

            config.timeout = 200000;



            numLoadings++;
            if (serialRequests == false) {

                $rootScope.$broadcast("open_requests", loadingspinner);
            } else {
                clearTimeout(timeO);
            }
        }

        return config || $q.when(config)
    },

    response: function (response) {

            serialRequests = true;
            numLoadings--;

            timeO = setTimeout(function () {
                serialRequests = false
                if ((numLoadings) === 0) {
                    $rootScope.$broadcast("all_requests_done");
                }
            });
        }
        return response || $q.when(response);
    },

    responseError: function (response) {

            serialRequests = true;
            numLoadings--;

            timeO = setTimeout(function () {
                serialRequests = false
                if ((numLoadings) === 0) {
                    $rootScope.$broadcast("all_requests_done");
                }
            });
        }
        return $q.reject(response);
    }


 };

使用$q.all():

var deferred = $q.defer();
var httpPromises = [];
for (var i = 0; i < docs.length; i++) {
    this.base64(docs[i], function(base64Img) {
        httpPromises.push($http.post(urls.BASE + '/store',{doc:base64Img});
        if (httpPromises.length === docs.length) {
            deferred.resolve();
        }
    }));
}

return deferred.promise.then(function() {
    return $q.all(httpPromises);
});

请注意,如果 this.base64() 返回一个承诺而不是在参数中接受回调,那会更简单:

var promises = [];
for (var i = 0; i < docs.length; i++) {
    promises.push(this.base64(docs[i]).then(function(base64Img) {
        return $http.post(urls.BASE + '/store',{doc:base64Img});
    }));
}
return $q.all(promises);

甚至

return $q.all(docs.map(function(doc) {
    return this.base64(doc).then(function(base64Img) {
        return $http.post(urls.BASE + '/store',{doc:base64Img});
    });
});