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

如何在Angular服务中实现同步方法?解决并发重复请求问题

解决Angular服务方法重复请求后端的问题

Angular没有提供类似Java/C#中synchronized的原生关键字,但可以借助RxJS的特性实现类似的“请求同步”效果,避免多个组件同时调用服务方法时重复发起后端请求。

核心思路是缓存当前正在进行的HTTP请求Observable,让后续请求直接订阅这个已存在的请求,而不是重新发起新请求。具体实现步骤如下:

修改服务代码

在CryptoMarketService中添加一个私有变量存储正在进行的请求,然后修改getActiveOrders方法:

export class CryptoMarketService implements MarketService {
  private _activeOrdersCache: Cache<Array<Order>> = new Cache<Array<Order>>();
  // 新增:存储当前正在进行的请求Observable
  private _activeOrdersRequest$: Observable<Array<Order>> | null = null;

  getActiveOrders(): Observable<Array<Order>> {
    // 1. 优先返回缓存数据
    if (this._activeOrdersCache.hasCache()) {
      return of(this._activeOrdersCache.get());
    }

    // 2. 如果已有正在进行的请求,直接返回该请求的Observable
    if (this._activeOrdersRequest$) {
      return this._activeOrdersRequest$;
    }

    // 3. 发起新请求并缓存请求Observable
    this._activeOrdersRequest$ = this.httpClient.get('/market/orders/active')
      .pipe(
        map((res: any) => Order.fromJsonArray(res)),
        tap((activeOrders: Array<Order>) => {
          this._activeOrdersCache.set(activeOrders, 5, TimeUnit.MINUTES);
        }),
        // 请求完成(成功/失败)后清空请求标记,避免后续请求被阻塞
        finalize(() => {
          this._activeOrdersRequest$ = null;
        })
      );

    return this._activeOrdersRequest$;
  }
}

方案原理

  • 第一个请求触发时,缓存为空且无正在进行的请求,因此发起HTTP请求并将该Observable存入_activeOrdersRequest$。
  • 后续同时调用的请求会直接返回这个已存在的Observable,共享同一个HTTP请求的响应结果,彻底避免重复请求后端。
  • 请求完成后(无论成功或失败),finalize操作符会清空_activeOrdersRequest$,确保缓存过期后,下一次请求能正常发起新的后端调用。

额外说明

如果需要处理请求失败的重试逻辑,可以在pipe中添加retry操作符,但要注意配合finalize确保请求标记最终会被清空,避免出现永久阻塞的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:22:51