Javascript 在$http拦截器中重新调用$http请求

Javascript 在$http拦截器中重新调用$http请求,javascript,angularjs,coffeescript,Javascript,Angularjs,Coffeescript,所以我截取了一个$http请求和响应。假设我有一个响应错误,我想重新调用我的$http调用。问题是我需要将$http服务注入我的拦截器,它会创建一个循环依赖项。这是我的coffeescript代码的简化版本: retryModule = angular.module('retry-call', []) retryModule.factory 'RetryCall', ($q, $http)-> # More object keys 'responseError': (respon

所以我截取了一个$http请求和响应。假设我有一个响应错误,我想重新调用我的$http调用。问题是我需要将$http服务注入我的拦截器,它会创建一个循环依赖项。这是我的coffeescript代码的简化版本:

retryModule = angular.module('retry-call', [])

retryModule.factory 'RetryCall', ($q, $http)->
  # More object keys
  'responseError': (response)=>
    # Retry request if failed
    # I need a different way of invoking $http() to avoid circular dependency
    $http(response.config)
    $q.reject(response)

retryModule.config ['$httpProvider', ($httpProvider)->
    $httpProvider.interceptors.push('RetryCall');
]

谢谢

为了避免循环依赖,您可以一直装饰
$http
服务来处理此功能。这是一张装饰师的照片

您基本上可以执行以下伪代码:

var old_post = $delegate.post;
$delegate.post = function(post_stuff) {
    var def = $q.defer();
    old_post(post_stuff).then(function(data) {
        if (data.error) {
            $delegate.post(post_stuff).then(function(data) {
                 def.resolve(data);
            }
        } else {
            def.resolve(data)
        }
    }, function(err_data) {
        // Also retry here
    });
};
return $delegate;
这基本上将原来的$http调用封装在您的重试功能中。该代码未经测试,因为它只是如何实现的基本概念。您还应该小心,因为这可能会创建一个无限循环


希望这有帮助

在查看Angular源代码之后,更好的答案是这样的$http方法无需依赖项注入即可访问,所以诀窍是不要注入$http,而只是简单地使用它。例如:

Right Way

retryModule = angular.module('retry-call', [])

# Do not inject $http
retryModule.factory 'RetryCall', ($q)->
  # More object keys
  'responseError': (response)=>
    # Just use $http without injecting it
    $http(response.config)
    $q.reject(response)

retryModule.config ['$httpProvider', ($httpProvider)->
    $httpProvider.interceptors.push('RetryCall');
]

Wrong Way

# Do not do it this way.
retryModule.factory 'RetryCall', ($q,$http)->

检查这个答案:我希望我能想到这一点。现在我觉得自己很笨,哈哈。