2017-02-20 60 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