取消/中止angularJs中的所有待处理请求

Kha*_* TO 7 javascript xmlhttprequest angularjs

在路由更改时,我需要中止来自先前路由的所有待处理请求,以便我不会遇到先前路由的响应问题,从而弄乱我当前路由上的数据(有时候,当前一路由的响应需要很长时间才能完成时) .

我曾考虑过使用http拦截器:

$httpProvider.interceptors.push(function($q) {
    return {
     'request': function(config) {

      },

      'response': function(response) {

      }
    };
  });
Run Code Online (Sandbox Code Playgroud)

在请求函数中,我可以config.timeout使用此处建议的promise 修改它,并将所有延迟对象存储在全局缓存中,以便我可以取消所有这些.

这种方法的问题在于它可能会覆盖 config.timeout代码中其他位置的set.

我认为另一种解决方案可能是取消所有XMLHttpRequest级别的ajax请求,但我不知道该怎么做.

有什么建议?谢谢.

Kas*_*wau 6

正如您所说,timeout我们现在唯一使用的API是取消正在运行的$ http请求.我认为你的拦截器加上取消承诺是对的.

您可以做的是在$http请求上附加完整的延迟对象,并取消路由更改处理程序中的所有pendingRequests.

像这样的东西可能(或许*)有效吗?

angular.module('module').config(function ($httpProvider) {
  $httpProvider.interceptors.push(function ($q) {
    return {
      request: function (config) {
        if (!config.timeout) {
          config.cancel  = $q.defer();
          config.timeout = config.cancel.promise;            
        }

        return config;
      }
    }
  });
});

angular.module('module').run(function ($rootScope, $http) {
  $rootScope.$on('$stateChangeStart', function () {
    $http.pendingRequests.forEach(function (pendingReq) {
      if (pendingReq.cancel) {
        pendingReq.cancel.resolve('Cancel!');
      }
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

*:我或许也许说,因为我采用这种方法取得了成功,但很少你能找到类似这样的银弹.


编辑

如果您需要绕过已取消的承诺的错误处理程序,请挂钩到responseError属性并在那里进行手工操作.

angular.module('module').config(function ($httpProvider) {
  $httpProvider.interceptors.push(function ($q) {
    return {
      responseError: function (response) {
        if (response.config.timeout.$$state.value === 'Cancel!') {
          // debugger; 
          return $q.when('bypassed');
        }
      }
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

我开始认为没有通用/"酷"的解决方案来达到你想要的最终结果.在这里走一些奇怪的地方:)


EDIT2:

现在自己测试一下.$q.when('something')responseError遗嘱中返回有效地绕过了取消$http请求的错误回调.如果它适合您,请告诉我.