Angular $ http,$ q:跟踪进度

时间:2013-08-06 04:07:46

标签: ajax angularjs

有没有办法跟踪Angular $ http和$ q的http请求进度?我正在从URL列表中进行$ http调用,然后使用$ q.all我将返回所有请求的结果。我想跟踪每个请求的进度(承诺已解决),以便我可以向用户显示一些进度。我想在承诺得到解决时发出事件,但我不确定它应该在哪里。

        var d = $q.defer();
        var promises = [];
        for(var i = 0; i < urls.length; i++){
            var url = urls[i];
            var p = $http.get(url, {responseType: "arraybuffer"});
            promises.push(p);
        }
        $q.all(promises).then(function(result){
            d.resolve(result);
        }, function(rejection){
            d.reject(rejection);
        });
        return d.promise;

修改 好吧,经过一番摆弄,这就是我想出来的

        var d = $q.defer();
        var promises = [];
        var completedCount = 0;
        for(var i = 0; i < urls.length; i++){
            var url = urls[i];
            var p = $http.get(url, {responseType: "arraybuffer"}).then(function(respose){
              completedCount = completedCount+1;
              var progress = Math.round((completedCount/urls.length)*100);
              $rootScope.$broadcast('download.completed', {progress: progress});
              return respose;
            }, function(error){
              return error;
            });
            promises.push(p);
        }
        $q.all(promises).then(function(result){
            d.resolve(result);
        }, function(rejection){
            d.reject(rejection);
        });
        return d.promise;

不确定这是否是正确的做法。

2 个答案:

答案 0 :(得分:6)

我发现您已经编辑了自己的代码,但如果您需要更全面的解决方案,请继续阅读

我曾经根据所有待处理的http请求制作了一个进度解决方案(显示某个正在加载的指示符,类似于youtube在最高进度条上)

<强> JS:

app.controller("ProgressCtrl", function($http) {

    this.loading = function() {
        return !!$http.pendingRequests.length;
    };

});

<强> HTML:

<div id="fixedTopBar" ng-controller="ProgressCtrl as Progress">
    <div id="loading" ng-if="Progress.loading()">
        loading...
    </div>
</div>

性交

对于我的最新项目,它并不仅仅需要请求电话。我开始涉及使用$q的套接字,webworker,文件系统,文件读取器,dataChannel和任何其他异步调用。所以我开始研究如何获得所有未决的承诺(包括$http)。事实证明,没有任何有角度的解决方案,所以我有点像decorating {{}}} {{}}} {{}}提供商{/ 1}}。{/ p>}

$q

这可能不适合每个人的生产需求,但它可能对开发人员有用,看看是否有任何未解决的问题被遗忘而且永远不会被称为

答案 1 :(得分:4)

制作一个小的一般辅助函数:

function allWithProgress(promises, progress) {
    var total = promises.length;
    var now = 0;
    promises.forEach(function(p) {
        p.then(function() {
            now++;
            progress(now / total);
        });
    })
    return $q.all(promises);
}

然后使用它:

var promises = urls.map(function(url) {
    return $http.get(url, {responseType: "arraybuffer"});
});

allWithProgress(promises, function(progress) {
    progress = Math.round(progress * 100);
    $rootScope.$broadcast('download.completed', {progress: progress});
}).catch(function(error) {
    console.log(error);
});