角度同步http循环更新进度条

时间:2013-09-26 19:38:17

标签: 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: d                  
        }).then(function(res){
            x++;
            update_progress((x/queue_count)*100);
        });
    }
});

我想在http返回完成时调用update_progress函数(200 OK),因此进度条正确显示实际进度。谢谢!

修改

我在调用* 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-strange

2 个答案:

答案 0 :(得分:13)

以下是顺序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 documentation

答案 1 :(得分:0)

你可以尝试这样的事情。等待发送下一个请求,直到上一个请求完成?

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