拦截器:具有重试的超时模态

时间:2017-02-20 20:55:21

标签: angularjs

我正在尝试编写一个角度拦截器(我在离子上)。 目标是拦截超时请求(让我们假设那些状态为-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);
      }
    }
  });
}]);

1 个答案:

答案 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语句。

DEMO on PLNKR.

为了避免“厄运金字塔”的嵌套,可以将这些承诺链接起来:

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