HttpClient的文档说明了以下关于不变性的内容:
存在拦截器来检查和改变传出请求和传入响应。但是,得知 HttpRequest 和 HttpResponse 类在很大程度上是不可变的可能会令人惊讶。
这是有原因的:因为应用程序可能会重试请求,拦截器链可能会多次处理单个请求。如果请求是可变的,则重试请求将与原始请求不同。不变性确保拦截器在每次尝试中看到相同的请求。
我觉得很难理解这个解释。有人可以提供解释吗?
HttpClient的文档说明了以下关于不变性的内容:
存在拦截器来检查和改变传出请求和传入响应。但是,得知 HttpRequest 和 HttpResponse 类在很大程度上是不可变的可能会令人惊讶。
这是有原因的:因为应用程序可能会重试请求,拦截器链可能会多次处理单个请求。如果请求是可变的,则重试请求将与原始请求不同。不变性确保拦截器在每次尝试中看到相同的请求。
我觉得很难理解这个解释。有人可以提供解释吗?
这个解释在不知道源代码的情况下是很难理解的。在 Angular 中的拦截器和 HttpClient 机制的 Insider 指南一文中对此进行了深入解释。
当你调用 的任何方法时http
,get
Angular 都会创建一个请求。然后这个请求被用来启动一个可观察的序列,当订阅这个请求时,这个请求通过拦截器链传递。这是作为序列处理的一部分完成的(非常简化的代码):
function get() {
let req: HttpRequest<any> = new HttpRequest<any>();
const events$ = of(req).pipe(concatMap((req: HttpRequest<any>) => {
// running request through interceptors chain
this.handler.handle(req);
}));
return $events;
}
以下是消息来源的评论:
从 Observable.of() 初始请求开始,然后在 concatMap() 中运行处理程序(包括所有拦截器)。这样,处理程序在 Observable 链中运行,这导致拦截器在每个订阅上重新运行(这也使得重试重新运行处理程序,包括拦截器)。
所以$events
流是从http请求方法返回的,可以重试。拦截器应始终从原始请求开始。如果请求是可变的并且可以在之前的拦截器运行期间进行修改,则无法满足此条件。所以请求及其所有组成部分应该是不可变的。