You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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)!;
    }
}

核心逻辑说明

  1. 按请求体区分缓存:通过JSON.stringify(body)生成唯一key,确保相同请求体的请求共用缓存,不同请求体的请求独立存储、独立发起。
  2. 缓存请求Promise而非结果:当第一个请求发起时,将处于pending状态的Promise存入Map,后续相同请求的调用直接复用这个Promise,等待同一请求完成,彻底避免重复API调用。
  3. 失败处理机制:请求失败时自动删除对应缓存项,确保下次相同请求会重新发起,不会一直返回失败结果。

组件使用说明

你现有的TestApiComponent和SetApiComponent代码无需任何修改,直接调用getApiData即可满足需求:

  • 当两个组件并行调用getApiData({"id":"1001"})时,只会发起一次API请求,请求完成后两个组件都会拿到相同的返回数据。
  • 若调用不同请求体(如{"id":"1002"}),则会发起独立的API请求,与其他请求体的缓存互不干扰。

内容的提问来源于stack exchange,提问作者saiteja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:35:10