首页 > 解决方案 > Angular HTTP 拦截器一个接一个地发出请求

问题描述


问题:我正在使用的 Angular 应用程序在构造方面非常复杂。有许多相同组件实例在同一个地方(父组件)输入不同数据的情况,每个组件都是在应用程序中显示的不同图表,例如:
<sample-component [data]='data1> </sample-component> <sample-component [data]='data2> </sample-component> <sample-component [data]='data3> </sample-component> ... so on
所以在每种情况下,这些数据的处理方式都不同,并且基于每个组件都是对相同的 API 端点进行相同的调用。所以问题是从多个组件实例突然多次执行调用,这会导致应用程序性能或服务器的请求过多。

示例解决方案:我在考虑 Angular HTTP Interceptor 以及如何使用这个工具捕获每个请求并使其在前一个请求被解决时执行,这样他们就会一个接一个地触发。到目前为止,我实现了拦截器,并且能够访问来自 Observable 的每个 HTTP 事件或请求,但是从这一点开始,我不知道如何或是否可以继续“延迟”它们。(我仍在学习 RxJs 和 Angular 相关的东西)
我也不确定这是否是合法的解决方案或是否有另一种做法 - 可能更好的解决方案是构建更优化的应用程序。还听说过缓存 HTTP 请求等机制。如果无法在“全局”级别正确处理这些请求,我猜我将不得不深入应用程序以重建其结构。

提前致谢

标签: angularhttprxjsinterceptorangular-http-interceptors

解决方案


我认为解决这个问题的一种方法是使用外观服务。

chart.facade.ts

chartData$: Observable<any>;

loadChartData () {
 this.chartData$ = this.http.get(...).pipe(shareReplay({ bufferSize: 1, refCount: true }));
}

父组件.ts

ngOnInit () {
 this.charFacade.loadChartData();
}

现在我想说这取决于你如何组织事情,但据我了解,每个sample-component人都会自己进行 http 调用。

样本.component.ts

// chartFacade.chartData$ - instantiated in `parent` component
this.chartData$ = this.chartFacade.chartData$;

constructor (private chartFacade: ChartFacade) { }

每次您chartData$ | asyncsample组件的模板中执行此操作时,都应该只进行一次 http 调用,并且应该从ReplaySubject的缓存中检索结果。

refCount === true,如果没有活动订阅(例如:每个sample组件都被销毁),则ReplaySubject使用的 byshareReplay将被丢弃,这意味着当再次加载这些组件时,将发生 http 调用,其结果将由 new 存储ReplaySubject

这是关于 Facades 的演讲。


推荐阅读