4

HttpClient的文档说明了以下关于不变性的内容:

存在拦截器来检查和改变传出请求和传入响应。但是,得知 HttpRequest 和 HttpResponse 类在很大程度上是不可变的可能会令人惊讶。

这是有原因的:因为应用程序可能会重试请求,拦截器链可能会多次处理单个请求。如果请求是可变的,则重试请求将与原始请求不同。不变性确保拦截器在每次尝试中看到相同的请求。

我觉得很难理解这个解释。有人可以提供解释吗?

4

1 回答 1

11

这个解释在不知道源代码的情况下是很难理解的。在 Angular 中的拦截器和 HttpClient 机制的 Insider 指南一文中对此进行了深入解释。

当你调用 的任何方法时httpgetAngular 都会创建一个请求。然后这个请求被用来启动一个可观察的序列,当订阅这个请求时,这个请求通过拦截器链传递。这是作为序列处理的一部分完成的(非常简化的代码):

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请求方法返回的,可以重试。拦截器应始终从原始请求开始。如果请求是可变的并且可以在之前的拦截器运行期间进行修改,则无法满足此条件。所以请求及其所有组成部分应该是不可变的。

于 2017-12-21T17:50:07.097 回答