Twitter bootstrap 用于更新进度条的角度同步http循环

Twitter bootstrap 用于更新进度条的角度同步http循环,twitter-bootstrap,angularjs,Twitter Bootstrap,Angularjs,我试图在foreach中用一个连续的http请求更新一个进度条,这是可行的,但在完成时它不是同步的,进度条被http调用同步,我做错了什么 angular.forEach(queue, function (item) { if (item.uid) { d.item = item; $http({ url: BASE_URL + 'upp', method: 'post', data

我试图在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返回为finished(200OK)时调用update_progress函数,以便进度条正确显示实际进度。谢谢

编辑

在调用*update_progress*函数之前,我尝试检查响应状态,但它仍然无法按预期工作。我不知道200是在请求完成之前发送的:|根据逻辑,resobj不应该是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);
        }
    });
}
阅读更多关于承诺自动取款机的文章,看看我是否能像@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();
});
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;
  })

});

谢谢@josh strange

你可以试试这样的东西。只需等待发送下一个请求,直到上一个请求完成

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);
      }
    });
  }
}
下面是一个连续http请求的工作示例。很明显,您可以在服务中很好地将其打包,但出于您的目的,我只在控制器中提供了一个简单的示例

以下是代码的“内容”:

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();
});
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在下面所说:这是一个链接承诺的示例,请参见。

不要使用forEach,手动循环队列?我也不确定这是否行得通。异步有时会很痛苦。您可以在AngularJS中进行同步调用,但也可以进行顺序http调用(Reg 1,然后Reg 2,等等)。让我试着为你准备一个小礼物。这是一个非常简单的连续HTTP请求示例,我将在一分钟内发布一个答案,并将其清理干净。@AntonioMax下面的答案是否解决了您的问题?@josh strange试图在我的代码上实现逻辑。如果工作正常,将更新并接受。以前从未创建过承诺,所以我正在阅读文档。为了完整起见,这是一个将承诺链接在一起的示例(请参见$q documentation@)。感谢您添加Mike,我将它添加到答案中!谢谢你的伟大解决方案,它很漂亮!谢谢,但是@josh strange Response更好,因为它使用承诺,我相信现在是正确的方式!