Angular 2+ 已缓存HTTP请求如何实现强制刷新、重新初始化缓存
实现强制刷新缓存的方案
你无需改动原有的组件初始化订阅逻辑,只需调整服务缓存逻辑,刷新时主动发起新请求并将新数据推送给所有订阅者即可,具体步骤如下:
1. 调整产品服务代码
修改原有服务的缓存逻辑,保留唯一的ReplaySubject实例避免旧订阅失效,新增强制刷新的触发逻辑:
// variables private readonly URL: string = 'http://makeup-api.herokuapp.com/api/v1/products.json'; // 直接初始化唯一的缓存Subject,所有订阅者共享同一个实例 private readonly cachingSubject: ReplaySubject<IProduct[]> = new ReplaySubject<IProduct[]>(1); private _products: IProduct[] = []; // 标记缓存是否已经完成过初始化 private isCached: boolean = false; //method public getAllProducts(forceRefresh: boolean = false): Observable<IProduct[]> { // 缓存未初始化 或 要求强制刷新时,发起新的HTTP请求 if (!this.isCached || forceRefresh) { this.http.get<IProduct[]>(this.URL) .subscribe((productsData: IProduct[]) => { this._products = productsData; this.isCached = true; // 新数据推送至Subject,所有已订阅的组件都会自动收到更新 this.cachingSubject.next(productsData); }); } return this.cachingSubject.asObservable(); } // 可选:单独封装强制刷新方法,调用更直观 public forceReload(): void { this.getAllProducts(true); }
2. 填充组件的强制刷新方法
直接调用服务提供的刷新方法即可,原有ngOnInit中的订阅会自动收到新数据并更新products变量:
public onForceReload(): void { // 两种调用方式二选一即可 // 方式1:调用封装好的刷新方法 this.productService.forceReload(); // 方式2:直接传参调用getAllProducts // this.productService.getAllProducts(true); }
可选优化:防止重复请求
如果担心短时间多次触发刷新会发起重复HTTP请求,可以新增请求状态标记做拦截:
// variables新增 private isRequesting: boolean = false; // getAllProducts修改为 public getAllProducts(forceRefresh: boolean = false): Observable<IProduct[]> { if ((!this.isCached || forceRefresh) && !this.isRequesting) { this.isRequesting = true; this.http.get<IProduct[]>(this.URL) .subscribe({ next: (productsData: IProduct[]) => { this._products = productsData; this.isCached = true; this.cachingSubject.next(productsData); }, complete: () => this.isRequesting = false, error: (err) => { this.isRequesting = false; this.cachingSubject.error(err); } }); } return this.cachingSubject.asObservable(); }
内容的提问来源于stack exchange,提问作者Олег Войтинський
相关产品推荐
相关产品推荐

