weixin_33705053 2013-08-06 04:07 采纳率: 0%
浏览 11

角$ http,$ q:跟踪进度

Is there a way to track progress of http requests with Angular $http and $q? I'm making $http calls from a list of urls and then using $q.all I'm returning result of all requests. I would like to track progress of each request (promise resolved) so that I can show some progress to the user. I'm thinking of emitting event when a promise gets resolved but I'm not sure where should that be.

        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;

EDIT: OK, after a bit of fiddling, this is what I've come up with

        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;

Not sure if it is the right way of doing it.

  • 写回答

2条回答 默认 最新

  • weixin_33744854 2014-03-11 22:59
    关注

    I see you have already edit your own code, but if you need a more overall solution, keep reading

    I once made a progress solution based on all pending http request (showing a indicator that something is loading, kind of like youtube has on the top progress bar)

    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>
    

    .

    Hardcore

    For my latest project it wasn't just enought with just request calls. I started to get into sockets, webworker, filesystem, filereader, dataChannel and any other asynchronous calls that use $q. So i start looking into how i could get all the pending promises (including $http). Turns out there wasn't any angular solution, so i kind of monkey patched the $q provider by decorating it.

    app.config(function($provide) {
    
        $provide.decorator("$q", function($delegate) {
            // $delegate == original $q service
    
            var orgDefer = $delegate.defer;
            $delegate.pendingPromises = 0;
    
            // overide defer method 
            $delegate.defer = function() {
                $delegate.pendingPromises++; // increass
                var defer = orgDefer();
    
                // decreass no mather of success or faliur
                defer.promise['finally'](function() {
                    $delegate.pendingPromises--;
                });
    
                return defer;
            }
    
            return $delegate
        });
    
    });
    
    app.controller("ProgressCtrl", function($q) {
    
        this.loading = function() {
            return !!$q.pendingPromises;
        };
    
    });
    

    This may not perhaps fit everyone needs for production but it could be useful to developers to see if there is any unresolved issues that has been left behind and never gets called

    评论

报告相同问题?