2016-02-13 109 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