如何用Angular和RxJS实现多组件同请求体仅单次API调用与缓存?
解决Angular中同一请求体仅发起单次API调用的问题
你的现有缓存服务存在两个核心问题:一是用单个变量存储缓存,无法区分不同请求体的请求;二是当请求处于pending状态时,后续调用会因为缓存未填充而重复发起API请求。以下是针对性的解决方案:
修改后的ApiCacheService实现
import { Injectable } from "@angular/core"; import { firstValueFrom } from "rxjs"; @Injectable({ providedIn: 'root' }) export class ApiCacheService{ // 用Map存储不同请求体对应的请求Promise,key为请求体的JSON字符串(确保相同请求体生成唯一标识) private cache = new Map<string, Promise<any>>(); constructor( private _api_service: ApiService ) { } /** * 清空所有缓存 */ public clearApiCache() { this.cache.clear(); } /** * 根据特定请求体清除对应缓存 * @param body 请求体 */ public clearCacheByBody(body: any) { const key = JSON.stringify(body); this.cache.delete(key); } /** * 获取API数据,同一请求体仅发起一次请求 * @param body 请求体 * @returns 数据Promise */ public async getApiData(body: any) { const key = JSON.stringify(body); // 检查是否已有该请求体对应的请求Promise if (!this.cache.has(key)) { // 创建请求Promise并存入缓存 const requestPromise = firstValueFrom(this._api_service.getData(body)) .then(res => res) .catch(err => { // 请求失败时移除缓存,避免后续请求复用失败的Promise this.cache.delete(key); throw new Error(`API请求错误: ${err.message}`); }); this.cache.set(key, requestPromise); } // 返回缓存中的Promise(pending状态时会等待同一请求完成,已完成则直接返回结果) return this.cache.get(key)!; } }
核心逻辑说明
- 按请求体区分缓存:通过
JSON.stringify(body)生成唯一key,确保相同请求体的请求共用缓存,不同请求体的请求独立存储、独立发起。 - 缓存请求Promise而非结果:当第一个请求发起时,将处于pending状态的Promise存入Map,后续相同请求的调用直接复用这个Promise,等待同一请求完成,彻底避免重复API调用。
- 失败处理机制:请求失败时自动删除对应缓存项,确保下次相同请求会重新发起,不会一直返回失败结果。
组件使用说明
你现有的TestApiComponent和SetApiComponent代码无需任何修改,直接调用getApiData即可满足需求:
- 当两个组件并行调用
getApiData({"id":"1001"})时,只会发起一次API请求,请求完成后两个组件都会拿到相同的返回数据。 - 若调用不同请求体(如
{"id":"1002"}),则会发起独立的API请求,与其他请求体的缓存互不干扰。
内容的提问来源于stack exchange,提问作者saiteja
相关产品推荐
相关产品推荐

