Я пытаюсь использовать HTTP-Interceptor для обработки при истечении времени ожидания $ http и обеспечения что запрашивающая функция на самом деле получает ответ, после которого он выполняется. Retry request with $http interceptor работает для меня, но у него есть немедленная повторная попытка. То, что меня больше интересует, - подождать 5 секунд, а затем повторить попытку. Кроме того, я также хочу, чтобы пользователь мог инициировать немедленную повторную попытку.
То, что я пытаюсь сделать что-то вроде ниже:
joinApp.factory('httpResponseErrorInterceptor',function($q, $injector, $interval) {
return {
'responseError': function(response) {
if (response.status === 0) {
setTimeToRetry(5); //sets retry timeout to 5 seconds, and starts an interval to reduce the count every second
// should retry
$interval(function(response) {
if(getTimeToRetry() <= 0) { //when retry timeout gets to 0, then retry - this also allows for a method that sets the retry timeout to 0 earlier so that a user can make an immediate retry
var $http = $injector.get('$http');
return $http(response.config);
}
},1000)
}
// give up
return $q.reject(response);
}
};
});
joinApp.config(function($httpProvider) {
$httpProvider.interceptors.push('httpResponseErrorInterceptor');
});
(Как вы можете видеть, я очень свободно копироваться базовый код из этого связанного ответа)
Но что Я нахожу, что тогда, когда запрос $http
повторен, он успешно завершает HTTP-запрос, но код, который искал исходный ответ обещания, на самом деле не получает его после. Я УГАДАЮ, что это связано с тем, что существование $interval
действительно перемещает ответ за пределами потока, в который был сделан запрос, поэтому ответ не отправляется в тот же запросчик, но это предположение.
То, что я также пробовал, - это связать обещание $interval
с обещанием $http
. Что-то вроде
var retryIntervalPromise = $interval(function(response) {
if(getTimeToRetry() <= 0) { //when retry timeout gets to 0, then retry
var $http = $injector.get('$http');
return $http(response.config);
}
},1000)
.then(function() {
var $http = $injector.get('$http');
return $http(response.config);
});
return retryIntervalPromise
Но я был проинформирован о том, что единственное, что может быть сделано с $interval
обетование, чтобы отменить его, и это, похоже, не работать в любом случае.
Есть ли у кого-нибудь идеи, как это можно сделать? Или намерение работает, и я только что сделал что-то ужасно неправильно? Спасибо!
Не могли бы вы предоставить нам код для подачи запроса. Мое мышление состоит в том, что, поскольку вы выполняете повторную попытку, первоначальное обещание более недействительно, поэтому вам придется обновить свое ожидаемое обещание с помощью повтора. – kwangsa
Почему вы используете '$ interval', а не' $ timeout', если все, что вам нужно, это задержка? –
Я использую '$ interval', чтобы я мог - через взаимодействие с пользователем - установить время повтора на 0 и, следовательно, принудительно выполнить повторную попытку. –