2017-02-20 61 views
0

我想写一个角度拦截器(我在离子)。 目标是拦截超时输出请求(让我们假设它们具有状态-1),显示一个模式,然后重试,直到连接完成。 拦截器看起来像预期的那样行事,但是当连接恢复时,什么都不会发生。恐怕在$timeout内部有return $http(rejection.config);是不正确的。拦截器:超时模式与重试

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

恐怕是不正确的有$超时内返回$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); 
     }); 
     }); 
    }; 

承诺的.then方法返回一个新的承诺,做出决议到什么被返回给给.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); 
    }); 
}; 
+0

感谢详细的解答。得到它了。 – NoIdeaHowToFixThis