2016-02-13 108 views
18

當有新請求時,如何取消正在進行的Angular $ http請求?

我有一個角度的應用程序,以更新生活爲用戶類型。有時舊請求會在最新請求後完成,這意味着視圖會顯示錯誤的數據。有新的請求時,最簡單的方法是取消先前的請求?

使用Angular 1.5,它是值得的。

<input ng-model = "query" ng-keyup = "search()"/> 
{{results | json}} 

// In the controller: 
    $scope.search = function(){ 
     $http({ 
      method: "GET", 
      url: "/endpoint.php" 
      params: { 
       query: $scope.query 
      } 
     }).then(function(response){ 
      $scope.results = response.data; 
     }) 
    } 

一個解決方法我都試過:

// In the controller: 
    var canceler = $q.resolve(); // New 
    $scope.search = function(){ 
     canceler.resolve("Canceling old request");  // New 
     $http({ 
      method: "GET", 
      url: "/endpoint.php" 
      params: { 
       query: $scope.query 
      }, 
      timeout: canceler.promise // New 
     }).then(function(response){ 
      $scope.results = response.data; 
     }) 
    } 

在這種情況下,即使我調用$ HTTP請求之前canceler.resolve,請求變成爲「失敗」。

任何見解?

編輯:找到解決方案!

// In the controller: 
    var canceler = $q.defer(); 

    $scope.search = function(){ 
     canceler.resolve("cancelled"); // Resolve the previous canceler 
     canceler = $q.defer();  // Important: Create a new canceler! 
             // Otherwise all $http requests made will fail 
     $http({ 
      method: "GET", 
      url: "/endpoint.php" 
      params: { 
       query: $scope.query 
      } 
     }).then(function(response){ 
      $scope.results = response.data; 
     }) 
    } 

回答

5

解決方案是設置承諾,然後用每個搜索()取消它並重新初始化一個新的。這將取消可靠以往任何$ HTTP():

var canceler = $q.defer(); 

$scope.search = function() { 

    canceler.resolve(); 

    canceler = $q.defer(); 

    $http({ 
     method: "GET", 
     url: "/endpoint.php" 
     params: { 
      query: $scope.query 
     } 
     timeout: canceler.promise 
    }).then(function(response) { 
     $scope.results = response.data; 
    }) 
} 
11

當你開始一個新的搜索,調用cancel()功能。您可以使用resolved變量來確保您在啓動之前不會中止$http通話。事情是這樣的:

var canceler = $q.defer(); 
var resolved = false; 

var cancel = function() { 
    canceler.resolve("http call aborted"); 
}; 

$scope.search = function() { 
    if (resolved) { 
     cancel(); 
    } 

    canceler = $q.defer(); 
    resolved = true; 

    $http({ 
     method: "GET", 
     url: "/endpoint.php" 
     params: { 
      query: $scope.query 
     } 
     timeout: canceler.promise 
    }).then(function(response) { 
     $scope.results = response.data; 
     resolved = false; 
    }) 
} 

不要忘了在你的控制器/指令/服務注入$q

+0

嗯 - 我嘗試這個 - 'NG點擊=「取消();搜索();」'我仍然得到同樣的XHR在我的控制檯失敗。我也在注射$ q。 – schnauss

+0

@schnauss是否使用var canceler = $ q.resolve()或var canceler = $ q.defer();? – NMSL

+0

'var canceler = $ q.defer();'。我很難過。 – schnauss