gpt4 book ai didi

http - 我需要 AngularJS $http 服务的两个实例还是什么?

转载 作者:可可西里 更新时间:2023-11-01 15:05:31 24 4
gpt4 key购买 nike

我想为我的 $http 服务添加一个响应拦截器以进行错误处理。拦截器逻辑包括在必要时使用 $http 向服务器发送错误消息,但是我不想向服务器发送关于错误消息的错误消息,我的意思是,我想在发送错误时禁用我的拦截器向服务器发送消息。

我的想法是创建一个名为“remote_log”的服务,并将向服务器发送错误所需的所有代码放入其中。该服务当然会使用 $http 服务并将其包含在其依赖项列表中。

然后将拦截器的依赖添加到'remote_log'服务,并在需要向服务器发送错误时使用拦截器内部的'remote_log'。问题在于:

当 $http 服务仍未实例化/不可访问时,必须使用 $httpProvider 定义拦截器,因此,拦截器代码内部不能依赖于 $http 服务,因为会发生“循环依赖”错误。

我认为我唯一的选择是在我的“remote_log”中创建一个单独的 $http 服务实例,该实例不使用我在创建拦截器时设置的 $httpProvider 配置。我的问题是:我该怎么做?还有其他想法吗?

最佳答案

1。循环依赖问题。

那么,为什么会出现这个错误呢?以下是该过程的简要概述:

  1. 请求 $http 服务。
  2. $httpProvider 被要求构建它。
  3. 在构建过程中注册拦截器,请求 $http 服务尚不存在。
  4. 您收到“循环依赖”错误。


第一个解决方案。

使用 angular.injector() 创建你的依赖。请注意,您将创建另一个独立于您的应用程序的 $http 服务。

$httpProvider.interceptors.push(function($q) {
$injector = angular.injector();
return {
response: function(response) {
$injector.invoke(function($http) {
// This is the exterior $http service!
// This interceptor will not affect it.
});
}
};
});


第二种解决方案(更好)。

在您的拦截器中注入(inject) $injector 并在 $http 初始化后使用它来检索依赖项,就在您需要它们的时候。这些依赖项是您应用程序的注册服务,不会重新创建!

$httpProvider.interceptors.push(function($q, $injector) {
return {
response: function(response) {
$injector.invoke(function($http, someService) {
// $http is already constructed at the time and you may
// use it, just as any other service registered in your
// app module and modules on which app depends on.
});
}
};
});


2。拦截预防问题。

如果使用第二种方案,其实有两个问题:

  1. 如果您在您的内部使用 $http 服务拦截器,你最终可能会无限拦截:你发送请求,拦截器捕获它,发送另一个,捕获另一个,再次发送,依此类推。
  2. 有时您只想防止请求被拦截。

$http服务的'config'参数只是一个对象。您可以创建一个约定,提供自定义参数并在您的拦截器中识别它们。

例如,让我们将“nointercept”属性添加到配置中,并尝试复制每个用户请求。这是一个愚蠢的应用程序,但对于理解其行为很有用:

$httpProvider.interceptors.push(function($q, $injector) {
return {
response: function(response) {
if (response.config.nointercept) {
return $q.when(response); // let it pass
} else {
var defer = $q.defer();
$injector.invoke(function($http) {
// This modification prevents interception:
response.config.nointercept = true;
// Reuse modified config and send the same request again:
$http(response.config)
.then(function(resp) { defer.resolve(resp); },
function(resp) { defer.reject(resp); });
});
return defer.promise;
}
}
};
});

通过拦截器中的属性测试,可以防止 Controller 和服务中的拦截:

app.controller('myController', function($http) {
// The second parameter is actually 'config', see API docs.
// This query will not be duplicated by the interceptor.
$http.get('/foo/bar', {nointercept: true})
.success(function(data) {
// ...
});

});

关于http - 我需要 AngularJS $http 服务的两个实例还是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14681654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com