我正在尝试使用foreach中的顺序http请求更新进度条,这有效,但是它不是同步的,进度条正在通过http调用同步,我做错了什么?
angular.forEach(queue, function (item) {
if (item.uid) {
d.item = item;
$http({
url: BASE_URL + 'upp',
method: 'post',
data: d
}).then(function(res){
x++;
update_progress((x/queue_count)*100);
});
}
});
我想在 http 返回完成(200 OK(时调用 update_progress 函数,因此进度条正确显示实际进度。谢谢!
编辑:
在调用 *update_progress* 函数之前,我尝试检查响应状态,但它仍然无法按预期工作。我不知道在请求完成之前已发送了 200:|按照逻辑,res obj 不应该是 http 请求的响应吗?我的意思是,如果它是 200 而不是错误代码,那不应该意味着请求已完成吗?
angular.forEach(queue, function (item) {
if (item.uid) {
d.item = item;
$http({
url: BASE_URL + 'upp',
method: 'post',
data: d
}).then(function(res){
if(res.status == 200) {
x++;
update_progress((x/queue_count)*100);
}
});
}
阅读更多关于承诺 atm 看看我是否可以让它像@josh-strange所说的那样工作
编辑 2:
所以承诺是这样做的方法,所有请求都是按顺序发送的,因此进度条按预期工作,这是代码:
var promise = $q.all({});
// Had to init $q.all with an empty obj, 'cause null was trowing errors
angular.forEach(queue, function(item){
if (item.uid) {
promise = promise.then(function(){
d.item = item;
return $http({
url: BASE_URL + 'upp',
method: 'post',
data: d
}).then(function(res){
x++;
update_progress((x/queue_count)*100);
});
});
}
});
promise.then(function(){
end_js_update();
});
谢谢@josh奇怪
这是一个顺序 http 请求工作示例的工作 Plunker。您显然可以将其很好地打包到服务中,但出于您的目的,我只是在控制器中放置了一个简单的示例。
这是代码的"肉":
var app = angular.module('testApp',[]);
app.controller('myController', function($scope, $http, $q){
$scope.responses = [];
$scope.doneLoading = false;
var urls = [
'http://httpbin.org/ip',
'http://httpbin.org/user-agent',
'http://httpbin.org/headers'
];
var promise = $q.all(null);
angular.forEach(urls, function(url){
promise = promise.then(function(){
return $http({
method: 'GET',
url:url
}).then(function(res){
$scope.responses.push(res.data);
});
});
});
promise.then(function(){
//This is run after all of your HTTP requests are done
$scope.doneLoading = true;
})
});
编辑:正如Mike P在下面所说:这是链接承诺的示例,请参阅$q文档。
你可以尝试这样的事情。只是等到上一个请求完成再发送下一个请求?
var sendRequest = function(index) {
if (queue[index].uid) {
d.item = queue[index];
$http({
url: BASE_URL + 'upp',
method: 'post',
data: d
}).then(function(res){
if (index != queue.length - 1) {
x++;
update_progress((x / queue_count) * 100);
sendRequest(++index);
}
});
}
}
<button ng-click="vm.startFetchingKeysAndAnswers(vm.selectedTestReader.serial,vm.selectedTestReader.Type)"
ng-if="vm.isShowStartFetchingbtn==true" id="btnStartFetching"
type="button" class="btn btn-primary btn-font" style="/*margin-left: 20px;*/">
Start
</button>
<div class="progress" style="margin-top: 10px;">
<div id="progressBar" class="progress-bar progress-bar-striped active" role="progressbar"
aria-valuemin="0" aria-valuemax="100">
60 %
</div>
</div>
function startFetchingKeysAndAnswers(testReaderId, type) {
vm.fetchFailedResultKeysAndAnswers = [];
vm.apiCallCount = 0;
vm.isShowStartFetchingbtn == false;
document.getElementById("btnStartFetching").style.display = "none";
let errorCount = 0;
var promise = $q.all({});
angular.forEach(vm.studentForFetchKeysAndAnswers, function (item) {
promise = promise.then(function () {
let userName = type == 2 ? item.Gozine2UserName : KanoonUserName;
let password = type == 2 ? item.Gozine2Password : KanoonPassword;
return testReaderService.getKeysAndAnswers(testReaderId, userName, password, item.NationalNo, type)
.then(function (data) {
if (data.data.HasError) {
errorCount++;
vm.fetchFailedResultKeysAndAnswers.push(item);
}
vm.apiCallCount++;
let percent = vm.apiCallCount / vm.studentForFetchKeysAndAnswers.length * 100;
document.getElementById("progressBar").setAttribute("style", "width:" + percent + "%");
document.getElementById("progressBar").innerHTML = percent + "%";
})
});
});
promise.then(function () {
});
}