簡體   English   中英

使用$ http攔截器重試請求

[英]Retry request with $http interceptor

我確信有一種簡單的方法可以做我想做的事情,我只是無法繞過它。 如果失敗,我怎樣才能獲得角度的http攔截器來重試請求? 我想我必須在請求中建立某種承諾嗎? 然后在響應中我將不得不檢查響應是否是錯誤,如果是,那么做出承諾嗎? 怎么做的? 我一直試圖改變這里的例子: http//docs.angularjs.org/api/ng.$http

我試圖使用攔截器的原因是因為我需要在請求URL中添加令牌和其他一些東西,以及處理xdr的一些事情。

這是一個$ http攔截器(立即)重放超時請求(即響應狀態0)。 構建此示例有兩個非顯而易見的(對我來說)元素:

  1. 如何從攔截器中調用$ http - 簡單地將$ http添加到依賴項列表中並不能用作循環依賴項的角度抱怨
  2. 如何從響應對象引用原始請求以重試它

這個答案解決了這兩個主題,但涉及的更多,因此我在下面添加了簡化版本。

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。

所以它是這樣的(請注意,延遲對象在每次重試時都會傳遞):

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;
  }
}])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM