【问题标题】:Angular HttpClient multiple callsAngular HttpClient 多次调用
【发布时间】:2017-11-17 15:43:46
【问题描述】:

我在我的 Angular 5 应用程序中发现了一个令人不安的事实。

我的服务中的这个小电话:

interface U{
  name:string;
}
...

constructor(private http : *Http*, private httpC:HttpClient) // Http is deprecated - its a compare test

...
ping() //Test Debug func
  {
    let o:Observable<U> = this.httpC.get<U>(this.url + "user/1");

    o.subscribe(resp => {
      console.log("SUBSCRIBE1: Init:get:user:U: " + resp.name);
      return resp;
    },
    this.handleError);

    o.subscribe(resp => {
      console.log("SUBSCRIBE2: Init:get:user:U: " + resp.name);
      return resp;
    },
    this.handleError);

    o.toPromise().then(resp => {
      console.log("PROMISE: Init:get:user:U: " + resp.name);
      return resp;
    });
  }

现在在 ping() 调用 Angular/Browser 实际上调用了 3 次 "url/user/1" 每个听众一次(2 个订阅,1 个承诺)

以前是这样的吗?

我对 Observer 的理解是,我可以添加多个等待操作的“Listeners”。不触发动作。

这里有什么问题?更新后我的设置是否有问题?

一些说明或示例如何正确地做这样的事情会非常棒! 感谢您的任何意见。

编辑:我扩展了实验,进一步调用了已弃用的 HTTP 客户端,该客户端正在执行相同的操作。所以这似乎是设计使然。只是不明白如何在不调用多次的情况下多次捕获。

 ping() //Test Debug func
  {
    let o:Observable<U> = this.httpC.get<U>(this.url + "user/1");

    o.subscribe(resp => {
      console.log("SUBSCRIBE1: Init:get:user:U: " + resp.name);
      console.log(resp);
      //this.currentUser = resp;
      return resp;
    },
    this.handleError);

    o.subscribe(resp => {
      console.log("SUBSCRIBE2: Init:get:user:U: " + resp.name);
      console.log(resp);
      //this.currentUser = resp;
      return resp;
    },
    this.handleError);

    o.toPromise().then(resp => {
      console.log("PROMISE1: Init:get:user:U: " + resp.name);
      console.log(resp);
      //this.currentUser = resp;
      return resp;
    });

    o.toPromise().then(resp => {
      console.log("PROMISE2: Init:get:user:U: " + resp.name);
      console.log(resp);
      //this.currentUser = resp;
      return resp;
    });


    let call:string = this.url + "user/1";
    return this.http.get(call)
        .toPromise()
        .then(resp => {
          console.log("OLD HTTP PROMISE 1 " + resp);

          return resp;
        })
        .catch(this.handleError)
        .then(resp => {
          console.log("OLD HTTP PROMISE 2 " + resp);

          return resp;
        });
  }

这是 Chrome 网络在一次 ping 调用后显示的内容:

【问题讨论】:

  • 你能告诉我们他们触发了一个请求还是他们只是处理 1 个响应 3 次?
  • 我可以把 Chrom-Network 概览的截图发给你......
  • 我认为您的通话和订阅不应该在同一个功能中。您通常会将订阅者放在一个组件中,并从服务发出请求。
  • 是的,这就是通常的用例。但无论如何我只是明白这一点。如果它在返回 Promise/Observable 后正常工作,那会让我更加困惑 :)
  • ...还有一个有趣的事实:使用 'HttpClient' 调用并仅监听 '.toPromise()' 不会触发任何 Angular 拦截器。

标签: typescript observable angular5


【解决方案1】:

我对观察者的理解是,我可以添加多个等待动作的“监听器”。不触发动作。

我认为您将subscribe() 与承诺的then() 混淆了。但与 promise 不同,后续调用 then 将返回完全相同的结果,在“冷”可观察对象上调用 subscribe() 不会订阅“相同”结果,但实际上会创建一个新的“生产者”每个subscribe() 调用和每个“生产者”都将生成(“生产”)一个新的不同结果。要对冷热可观察物进行很好的解释,请考虑阅读 Ben Lesh 的 this 精彩文章。

这里有什么问题?更新后我的设置是否有问题?

我上面描述的是在您的示例中也发生了HttpClientget():它创建了一个冷可观察对象,其生产者(即请求)将在每次调用时重新创建(重新执行)。

您可以使用 rxJS share() 或在您的情况下最好使用 shareReplay,即 replays values,使客户端的“冷”http 请求可观察到“热”,即共享 objservable 的源/序列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多