AngularJS:使用超时属性取消$ http请求

Serlingpa

我已经看到了很多关于该主题的文章,以及许多Web文章,但是我仍然为自己的问题感到困惑。我发现这篇文章非常有用,但是我的timeoutRequest()函数从未被调用过。

我正在使用带有$ http超时属性的promise,但是基础HTTP请求没有被取消。我认为诺言本身已得到解决,但请求并未取消。

我的控制器行为如下所示:

$scope.enquiriesSelected = function() {
    $scope.cancelHttpRequests();
    $location.path("/enquiries");
};

$scope.cancelHttpRequests = function () {
    console.log(canceller.promise.$$state);
    canceller.resolve("User cancelled");
    console.log(canceller.promise.$$state);
};

我的HTTP请求承诺如下所示:

var canceller = $q.defer();

$scope.searchResultsPromise = $http({
        url: "/api/customers/customersearch",
        method: "POST",
        data: criteria,
        timeout: canceller.promise 
    })
    .success(function(data) {
        $scope.customerSearchResults = data;
    });

我尝试了各种方法使它起作用,包括将取消器放入$ scope中。

我一直在浏览AngularJS源代码,发现以下几行:

if (timeout > 0) {
    var timeoutId = $browserDefer(timeoutRequest, timeout);
} else if (isPromiseLike(timeout)) {
    timeout.then(timeoutRequest);
}

function timeoutRequest() {
    jsonpDone && jsonpDone();
    xhr && xhr.abort();
}

但是,当我的诺言得到解决时,执行路径不会到达这些行。永远不会调用xhr.abort(),这是AngularJS源代码中唯一中止HTTP请求的地方。

尝试取消请求时,使用F12(Chrome)中的控制台进行检查会发现,承诺的$$状态从0更改为1,因此我有把握地确定承诺已得到解决。但是,在网络流量中,HTTP请求不会被取消。在HTTP请求完成之前,我无法导航到另一个页面。

有人可以帮忙吗?

中号

克里斯蒂娜(Christina)

您所描述的实际上是$http使用timeout属性取消请求的正确方法我创建了这个Plunkr,它展示了这种行为与您提供的代码尽可能接近。您会看到,单击“带超时的提交请求”按钮后,将提交一个请求,并在100毫秒后解决超时承诺(由于请求返回的速度非常快,您实际上没有时间单击某些东西来取消它) :

$scope.requestWithTimeout = function() {
  $timeout(function(){canceller.resolve("User cancelled");}, 100);
  $scope.submitRequest();
}

$ http请求错误回调检查响应的状态并显示相应的错误消息,您可以在其中看到100毫秒后实际上已取消了该请求。您还可以通过观察浏览器开发人员工具的“网络”标签中的请求来验证这一点。

$scope.submitRequest = function() {
    // Reset the canceler promise
    canceller = $q.defer();
    $scope.status = 'Request submitted';
    var startTime = (new Date()).getTime();
    $http({ 
      url: 'style.css',
      method: 'GET',
      timeout: canceller.promise 
    })
    .success(function(data) {
      var endTime = (new Date()).getTime();
      $scope.status = 'Request response returned after ' + (endTime - startTime) + ' msec.';
    })
    .error(function(data, status) {
      var endTime = (new Date()).getTime();
      if(status === 0) {
        $scope.status = 'Request timed out after ' + (endTime - startTime) + ' msec.';
      } else {
        $scope.status = 'Request returned with error after ' + (endTime - startTime) + ' msec.';
      }
    });
  }

希望您可以以此为例来查找代码问题并进行更正。否则,请使用无效的代码创建一个Plunkr(或类似的东西),以便我进一步帮助您。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章