如何删除RXJS中的冗余请求?

问题描述 投票:0回答:5

我正在使用Rxjs和Angular Framework进行前端项目,我想从api“ api / data_processor_classlib.php ....”中获取json数据。在HTML中有3个部分已通过管道管道this.webProtectionHTML $进行了订阅。我不知道为什么管道this.webProtectionHTML $发出了3次请求。是否有可能仅发送一个请求并更新HTML中的所有数据的解决方案?谢谢。

HTML代码:

    <div class="tr">
      <div class="align-left">Phishing & Other Frauds</div>
      <div class="align-right">{{ (webProtectionHTML$|async)?.phishing}}</div>
    </div>
    <div class="tr">
      <div class="align-left">Spam URLs</div>
      <div class="align-right">{{ (webProtectionHTML$|async)?.spamURLs}}</div>
    </div>
    <div class="tr">
      <div class="align-left">Malware Sites</div>
      <div class="align-right">{{ (webProtectionHTML$|async)?.malware}}</div>
    </div>

Component:

this.webProtectionHTML$ = this.dayService$
      .pipe(
        mergeMap((days: DaysPeriod // params added to request url) => this.httpClient.get(`api/data_processor_classlib.php....`//request url, { responseType: 'text' })),
        map((html: string) => {
          //get html code and find data return as json data
          let result = this.getWebProtectionData(html)
          return result
        }))

网络日志:

enter image description here

angular rxjs rxjs5 rxjs6 rxjs-observables
5个回答
1
投票

之所以被称为三次,是因为每个async管道都会触发一个请求。相反,在这些情况下,您可以订阅组件并使用成员变量。然后,您可以在ngOnDestroy挂钩中取消订阅订阅,以避免内存泄漏。尝试以下]]

控制器

private dayServiceSubscription: Subscription;
public webProtectionHTML: any;

ngOnInit() {
  this.dayServiceSubscription = this.dayService$
    .pipe(
      mergeMap((days: DaysPeriod) => this.httpClient.get(`api/data_processor_classlib.php....`//request url, { responseType: 'text' })),
      map((html: string) => this.getWebProtectionData(html)))
    .subscribe(response => this.webProtectionHTML = response);
}

ngOnDestroy() {
  if (this.dayServiceSubscription) {
    this.dayServiceSubscription.unsubscribe();
  }
}  

模板

<div class="tr">
  <div class="align-left">Phishing & Other Frauds</div>
  <div class="align-right">{{ webProtectionHTML?.phishing}}</div>
</div>
<div class="tr">
  <div class="align-left">Spam URLs</div>
  <div class="align-right">{{ webProtectionHTML?.spamURLs}}</div>
</div>
<div class="tr">
  <div class="align-left">Malware Sites</div>
  <div class="align-right">{{ webProtectionHTML?.malware}}</div>
</div>

0
投票

因为您使用(webProtectionHTML$|async)调用了3次,所以每次调用它并显示另一个成员的值。如果您仅希望一次调用它,请在this.webProtectionHTML$constructor中调用ngOnInit并将返回的值分配给本地变量,您可以使用其值绑定到它。


0
投票

对于API,您可以使用toPromise方法按承诺返回。它将convert订阅promise。因此,即使您使用异步3 times。它将解决承诺once


0
投票

[一些先前的答案正确地指出,每次使用async管道都会导致http请求-但不解释原因。实际上,异步管道本身并不是问题。这是因为您的http请求可观察到的是“冷”(如此处的解释:https://www.learnrxjs.io/learn-rxjs/concepts/rxjs-primer#what-is-an-observable)。


0
投票

它发出了3个请求,因为代码在模板中为this.webProtectionHTML$指定了3个异步管道。

© www.soinside.com 2019 - 2024. All rights reserved.