4

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;

それが正しい方法であるかどうかはわかりません。

4

2 に答える 2

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>

.

ハードコア

私の最新のプロジェクトでは、リクエスト呼び出しだけでは十分ではありませんでした。ソケット、webworker、ファイルシステム、filereader、dataChannel、および を使用するその他の非同期呼び出しに取り組み始めました$q。そこで、保留中のすべての約束 (を含む) を取得する方法を調べ始め$httpました。$q角張った解決策がなかったことが判明したので、プロバイダーをデコレートしてパッチを当てまし

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;
    };

});

これはおそらく本番環境のすべてのニーズに適合するわけではありませんが、取り残され、呼び出されない未解決の問題があるかどうかを開発者が確認するのに役立つ可能性があります。

于 2014-03-11T22:59:51.763 に答える