有没有办法跟踪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;
不确定这是否是正确的做法。
答案 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);
});