我正在尝试编写一个角度拦截器(我在离子上)。
目标是拦截超时请求(让我们假设那些状态为-1),显示模态,然后重试直到连接通过。
拦截器似乎表现得如预期,但是当连接恢复时,没有任何反应。我担心return $http(rejection.config);
内的$timeout
是不正确的。
services.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function($injector, $q, $timeout) {
return {
// we use the incerceptor to assign a timeout property to every http request
request: function (config) {
config.timeout = 5000;
return config;
},
responseError: function(rejection) {
// We assume timeouts have status=-1
var $http = $injector.get("$http");
var $rootScope = $injector.get("$rootScope");
// duration defines how long the modal screen will be open (in seconds)
var duration = 5;
var showModalAndRetry = function(rejection) {
$timeout(angular.noop, 1000).then( function() {
$rootScope.$broadcast("app.somethingWentWrong");
$timeout(angular.noop, duration * 1000).then( function () {
$rootScope.$broadcast("app.closeSomethingWentWrong");
console.log("resending");
console.log(rejection);
return $http(rejection.config);
});
});
};
switch(rejection.status) {
case -1:
return showModalAndRetry(rejection);
}
return $q.reject(rejection);
}
}
});
}]);
答案 0 :(得分:1)
我担心在$ timeout
中返回$http(rejection.config);
是不正确的
//ERRONEOUS var showModalAndRetry = function(rejection) { $timeout(angular.noop, 1000).then( function() { $rootScope.$broadcast("app.somethingWentWrong"); $timeout(angular.noop, duration * 1000).then( function () { $rootScope.$broadcast("app.closeSomethingWentWrong"); console.log("resending"); console.log(rejection); return $http(rejection.config); }); }); };
promise的.then
方法返回一个新的promise,它解析为返回给.then
方法的函数的内容。将新承诺返回到父函数非常重要。否则,父函数返回值undefined
。
//INSTEAD
function showModalAndRetry (rejection) {
//vvvv RETURN timeout promise
return $timeout(angular.noop, 1000).then( function() {
$rootScope.$broadcast("app.somethingWentWrong");
//vvvv RETURN timeout promise
return $timeout(angular.noop, duration * 1000).then( function () {
$rootScope.$broadcast("app.closeSomethingWentWrong");
console.log(rejection);
return $http(rejection.config);
});
});
};
在这种情况下,有$timeout
个承诺嵌套在另一个$timeout
承诺中。每个嵌套级别都需要有return
语句。
为了避免“厄运金字塔”的嵌套,可以将这些承诺链接起来:
function showModalAndRetry (rejection) {
//vvvv RETURN timeout promise
return $timeout(null, 1000)
.then( function() {
$rootScope.$broadcast("app.somethingWentWrong");
//vvvv RETURN timeout promise
return $timeout(null, duration * 1000);
}).then( function () {
$rootScope.$broadcast("app.closeSomethingWentWrong");
console.log(rejection);
//vvvv RETURN httpPromise
return $http(rejection.config);
});
};