【问题标题】:Why do most classes of the HttpClient API define immutable objects?为什么 HttpClient API 的大多数类都定义了不可变对象?
【发布时间】:2017-12-21 17:48:52
【问题描述】:

documentation for HttpClient 声明了以下关于不变性:

拦截器的存在是为了检查和改变传出的请求和 传入的响应。然而,得知 HttpRequest 和 HttpResponse 类在很大程度上是不可变的。

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

我很难理解这个解释。有人可以解释一下吗?

【问题讨论】:

  • 我有点等着有人在 SO 中添加这个资源,因为这个问题在这里和 github 上的 angular repo 的问题跟踪器中出现了多次
  • @Jota.Toledo,是的,这个问题也困扰了我一段时间。我现在正在完成一篇大文章,解释拦截器如何在后台工作,并将这个问题作为我调查的一部分。

标签: angular immutability angular-httpclient


【解决方案1】:

这个解释在不知道the source code的情况下很难理解。在Insider’s guide into interceptors and HttpClient mechanics in Angular一文中有深入的解释。

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

【讨论】:

    猜你喜欢
    • 2019-11-23
    • 2023-03-21
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    相关资源
    最近更新 更多