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

如何用RxJS的shareReplay缓存多重复URL的HTTP请求?

重复URL请求缓存解决方案

原代码的核心问题:

  • 空的allUrls$没有实际数据源,后续流操作都是无效的
  • mergeMap(() => this.allUrls$)会触发循环订阅,逻辑完全错误
  • 调用cacheUrl后既没订阅也没把结果合并到流里,请求根本没发起
  • 缓存逻辑和流的联动缺失,无法正确跟踪已请求的URL

下面是修正后的实现,用RxJS的Observable缓存机制,确保同一URL只发起一次请求:

// 缓存已发起的请求流:key为URL,value为对应请求的Observable
private urlCache = new Map<string, Observable<{ ...someproperties; url: string }>>();

fetchRequest(urls: string[]) {
  // 为每个URL生成对应的请求流,重复URL直接复用缓存
  const requestStreams = urls.map(url => {
    if (!this.urlCache.has(url)) {
      // 首次请求:创建请求流并缓存,shareReplay确保结果被复用
      const stream$ = this.cacheUrl(url).pipe(shareReplay(1));
      this.urlCache.set(url, stream$);
    }
    return this.urlCache.get(url)!;
  });

  // 合并所有请求流,返回当前传入URL对应的响应数组
  return forkJoin(requestStreams).pipe(
    map(responses => responses.filter(res => urls.includes(res.url)))
  );
}

核心逻辑说明

  • urlCache Map用来记录每个URL的请求Observable,彻底避免重复请求
  • shareReplay(1)会缓存请求结果,后续同一URL的请求直接拿缓存的结果,不用重新发起API调用
  • forkJoin等待所有请求完成后返回响应数组,再过滤出当前需要的结果

如果需要处理请求中的状态(比如某个URL正在请求时,重复调用fetchRequest也会返回同一个请求流,不会重复发起),这个方案天然支持,因为shareReplay会共享同一个订阅实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:06:27