2013-09-26 61 views
3

我試圖用foreach中的順序http請求來更新進度條,這可以工作,但它不完全同步,進度條正在通過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); 
     }); 
    } 
}); 

我想打電話給update_progress函數只是當HTTP返回爲成品(200 OK),所以進度條正確顯示的實際進展。謝謝!

編輯

我試圖檢查響應狀態,調用* update_progress *函數之前,它仍然沒有按預期工作。我並不知道在請求完成之前發送了200個:|通過邏輯,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,看看我能使其工作,通過@喬希怪

編輯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(); 
}); 

感謝@喬希怪

+0

不要使用forEach,手動循環隊列嗎?不知道這也可以。異步可能有時是一種痛苦。 – aet

+0

你[不能](http://stackoverflow.com/questions/13088153/how-to-http-synchronous-call-with-angularjs)在AngularJS中進行同步調用,但你可以進行順序的http調用(Reg 1,然後Reg 2等)。讓我試着讓你的朋友聚在一起。 – JoshStrange

+0

[Here](http://plnkr.co/edit/HMccomnJooWpIHFMO4H8)是連續HTTP請求的一個非常簡單的例子,我會在一分鐘後發佈一個答案,並將其清理乾淨。 – JoshStrange

回答

13

這是一個工作的Plunker順序http請求的工作示例。你可以很明顯地把它打包在一個服務中,但爲了你的目的,我只是把它的一個簡單的例子放在一個控制器中。

這裏是代碼「肉」:

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

}); 

編輯:由於邁克·P下面說:這是鏈接的承諾看$q documentation一個例子。

+2

爲了完整起見,這是將承諾鏈接在一起的示例(請參閱$ q documentation @ http://docs.angularjs.org/api/ng.$q)。 –

+0

感謝您加入Mike,我會將其添加到答案中! – JoshStrange

+0

它正在工作。謝謝!查看我的編輯。 –

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

謝謝你,但@Josh奇怪的答案是更好的,因爲它使用承諾,我相信現在是做到這一點的正確方法! –