我有一个“可取消的”angularJs $http呼叫,如下所示:
var defer = $q.defer() $http.post("http://example.com/someUrl",{some: "data"},{timeout: defer.promise})
而且我取消了使用defer.resolve()的ajax请求,因为某些逻辑需要它.
有些在我的代码中,我有一个这样的迭代:
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); } }; }); }); });
问题:
如果有Internet连接问题,ajax将失败,状态为0,拦截器捕获它.
如果ajax被超时承诺取消,那么状态也是0,拦截器捕获它.
我找不到它是否被取消或在responseError处理程序中有错误.
我的天真的方法是检查超时是否定义如下:
responseError: function(rejection) { if(rejection.status == 0 && !rejection.config.timeout) { alert("check your connection"); } return $q.reject(rejection); }
它只保证,该请求有一个超时条件,而不是因为它失败.但它比没有更好.
有没有确定ajax是否失败或取消的真正有效的方法?
我使用AngularJs 1.1.5
我最后使用一个标志,这是在错误处理程序中检查.
我开始遵循这个AngularJS Github问题结尾处的建议:https://github.com/angular/angular.js/issues/1159#issuecomment-25735438
这导致我建立一个服务,使用承诺来手动“超时”http呼叫 – 如下所述 – 通过复制链接的plunk从该问题:http://plnkr.co/edit/P8wKns51GVqw5mwS5l5R?p=preview
但这并不完全,因为这并没有解决你提出的问题.在错误处理中,如何确定呼叫是否是真正的服务器中断/超时,还是简单的手动触发超时.最后,我不得不诉诸于将其存储在另一个变量(类似于超时承诺),这可以在这个plunk中看到: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 !"); } }); }; };
不太优雅,但它似乎工作,并避免任何讨厌的种族条件从我观察到.