使用$http拦截器重试请求
Retry request with $http interceptor
我相信有一种简单的方法可以做我想做的事情,我只是无法理解它。如果请求失败,我如何让http拦截器处于angular状态来重试请求?我想我必须在请求中做出某种承诺,对吧?然后在响应中,我必须检查响应是否是错误的,如果是,是否承诺?这是怎么做到的?我一直在尝试调整这里的示例:http://docs.angularjs.org/api/ng.$http
我尝试使用拦截器的原因是,我需要向请求url添加令牌和其他一些东西,以及一些处理xdr的东西。
这里有一个$http拦截器,它(立即)重放超时的请求(即响应状态0)。构建这个例子有两个不明显的元素(对我来说!):
- 如何从拦截器中调用$http——简单地将$http添加到依赖项列表中是不起作用的,因为angular抱怨循环依赖项
- 如何引用响应对象的原始请求以重试
这个答案解决了这两个主题,但涉及更多,所以我在下面包含了一个简化版本。
joinApp.factory('httpResponseErrorInterceptor',function($q, $injector) {
return {
'responseError': function(response) {
if (response.status === 0) {
// should retry
var $http = $injector.get('$http');
return $http(response.config);
}
// give up
return $q.reject(response);
}
};
});
joinApp.config(function($httpProvider) {
$httpProvider.interceptors.push('httpResponseErrorInterceptor');
});
在实际实现中,您可能需要更复杂的http响应代码处理、重试次数的限制等。
为了完整起见,这里有一个带有重试延迟的mygzi答案版本:
.factory('httpResponseErrorInterceptor', ['$injector', '$q', '$timeout', function($injector, $q, $timeout) {
return {
'responseError': function(response) {
if (response.status === 0) {
return $timeout(function() {
var $http = $injector.get('$http');
return $http(response.config);
}, 15000);
}
return $q.reject(response);
}
};
}])
.config(function($httpProvider) {
$httpProvider.interceptors.push('httpResponseErrorInterceptor');
});
$timeout
返回一个promise,该promise由函数参数返回的内容完成,因此我们可以方便地返回封装在$timeout
中的$http
调用。
我为之前编写的一个应用程序做过这件事。要进行重试,请将$http用法封装在函数中(最好是在服务中,以便您可以轻松地重用它)。如果请求失败,请再次调用该函数。
诀窍是将promise对象与每个请求一起传递。如果你为每个请求创建一个新的promise,那么它将与你返回给原始调用者的promise不匹配,所以一旦请求通过,原始调用者就不会得到他的promise解析。
所以它是这样的(注意,在每次重试中都会传递defer对象):
app.service('HttpService', ['$q', function($q) {
this.makeRequest = _makeRequest;
function _makeRequest(url, data, deffered) {
// We want to keep the same promise for each request, so we don't loose track
if (deferred === undefined) {
deferred = $q.defer();
}
// Now make the request
$http({...}).success(...).error(
function(){
// If some condition
_makeRequest(url, data, deffered);
}
)
// Lastly return the promise
return deferred.promise;
}
}])
相关文章:
- JavaScript:在源404上重试
- 用分隔符分隔具有多个整数值的字符串的Javascript"重试错误的值
- Ajax在NodeJS中为一个耗时的请求请求多次重试
- 如何在fetch post调用后管理重定向请求
- 如何仅在RxJs中可观察到的源发出的特定错误上重试
- BreezeJS中央错误处理程序和自动重试
- 如何捕获请求中的错误,然后打开模态,然后在模态使用RxJS关闭时重试
- Angular2 http重试逻辑
- JS重试函数几次,看看它是否返回true
- Promise中的递归重试
- Bluebird Promise 重试 DocumentDB 请求
- 脸书应用程序请求:发生错误.请稍后重试
- 用于处理成功、失败、重试的异步请求的设计模式?(JavaScript)
- 什么'这是在失败时使用jQuery重试AJAX请求的最佳方式
- Meteor-如何在不丢失上下文的情况下重试失败的HTTP请求
- Angular-重试失败的请求
- 在重试ajax请求之前,请检查浏览器中是否仍存在必要的DOM节点
- 全局配置所有$.ajax请求以支持超时重试
- 超时后重试ajax请求
- 如何重试xhr请求,该请求在状态0时递归返回promise至少n次