确定AJAX是否被取消或在AngularJs拦截器中出错

Umu*_*zer 15 angularjs

我有一个"可取消的"angularJs $http调用如下:

var defer = $q.defer()
$http.post("http://example.com/someUrl", {some: "data"}, {timeout: defer.promise})
Run Code Online (Sandbox Code Playgroud)

我取消了ajax请求,defer.resolve()因为某些逻辑需要它.


在我的代码中的其他地方,我有一个像这样的iterceptor:

angular.module("services.interceptor", arguments).config(function($httpProvider) {
     $httpProvider.interceptors.push(function($q) {
        return {
          responseError: function(rejection) {
            if(rejection.status == 0) {
              alert("check your connection");
            }
           return $q.reject(rejection);
        }
      };
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

问题:

如果存在Internet 连接问题,则ajax失败,状态为0,拦截器会捕获它.如果AJAX被取消超时承诺,比状态也为0,并拦截捕获它.

我无法确定它是否被取消或在responseError处理程序中出错.

我天真的方法是检查超时是否定义如下:

responseError: function(rejection) {
  if(rejection.status == 0 && !rejection.config.timeout) {
    alert("check your connection");
  }
  return $q.reject(rejection);
}
Run Code Online (Sandbox Code Playgroud)

它只能保证,还有就是对这项请求超时条件,没有它,因为它的失败.但总比没有好.

是否有确定ajax失败或取消的真正有效方法?

我正在使用AngularJs 1.1.5

Pha*_*ale 5

我最终使用一个标志执行此操作,该标志在错误处理程序中进行检查.

我开始关注AngularJS Github问题结束时的建议:https://github.com/angular/angular.js/issues/1159#issuecomment-25735438

这导致我构建了一个服务,它使用了一个承诺来手动"超时"http调用 - 如下所述 - 通过复制该问题的链接插件:http://plnkr.co/edit/P8wKns51GVqw5mwS5l5R?p = preview

但这并不完全,因为这并没有解决你提出的问题; 在错误处理中,如何确定调用是否是真正的服务器中断/超时,或者只是手动触发的超时.最后,我不得不求助于将它存储在另一个变量中(类似于超时承诺),这可以在这个插件中看到:http://plnkr.co/edit/BW6Zwu

该代码的主要方法如下所示

return function (url) {
    var cancelQuery = null;
    var queryCancelled = false;

    return function runQuery(query) {
      if (cancelQuery) {
        queryCancelled = true;
        cancelQuery.resolve();
      }
      cancelQuery = $q.defer();
      return $http.
        get(url, { params: { query: query }, timeout: cancelQuery.promise }).
        then(function (response) {
          cancelQuery = null;
          return response.data;
        }, function (error) {
          if(queryCancelled) {
            console.log("Request cancelled");
            queryCancelled = false;
          } else {
            console.log("Actual Error !");
          }
        });
    };
  };
Run Code Online (Sandbox Code Playgroud)

不是太优雅,但似乎有效,避免了我观察到的任何讨厌的竞争条件.