2015-05-18 2 views
1

Я пытаюсь использовать 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 обетование, чтобы отменить его, и это, похоже, не работать в любом случае.

Есть ли у кого-нибудь идеи, как это можно сделать? Или намерение работает, и я только что сделал что-то ужасно неправильно? Спасибо!

+0

Не могли бы вы предоставить нам код для подачи запроса. Мое мышление состоит в том, что, поскольку вы выполняете повторную попытку, первоначальное обещание более недействительно, поэтому вам придется обновить свое ожидаемое обещание с помощью повтора. – kwangsa

+0

Почему вы используете '$ interval', а не' $ timeout', если все, что вам нужно, это задержка? –

+0

Я использую '$ interval', чтобы я мог - через взаимодействие с пользователем - установить время повтора на 0 и, следовательно, принудительно выполнить повторную попытку. –

ответ

2

Вы можете вернуть обещание «задержки» от функции responseError, к которой вы связываете обещание $ http, чтобы попробовать еще раз. Это простой пример с фиксированным таймаута:

  responseError: function(response) { 
       if (response.status === 0) { 
        var $http = $injector.get('$http'); 

        var deferred = $q.defer(); 

        $timeout(function() { 
         deferred.resolve(true); 
        }, 5000); 

        return deferred.promise.then(function() { 
         return $http(response.config); 
        }); 
       } 
       return $q.reject(response); 
      } 

Если вам нужна переменная задержка, вы можете сохранить его в переменной внутри завода или другой службы и имеют остальные изменения пользовательского интерфейса там. В следующий раз, когда срабатывает тайм-аут, он будет считывать новое значение интервала из синглтона и ждать соответственно до повторного запуска запроса.

+0

Это отличный способ отложить решение обещания. Именно то, что я искал. – Alex

Смежные вопросы