如何在 Angular 服务中创建同步方法?

Ale*_*lov 2 observable rxjs typescript angular

我有一个 Angular 15 应用程序,其中有一些组件调用服务方法从后端检索一些数据。在执行之前,服务会检查本地缓存中是否有所需的数据。如果没有数据,则服务执行端点并将检索到的数据存储在缓存中。在代码中看起来是这样的:

export class CryptoMarketService implements MarketService {
   private _activeOrdersCache: Cache<Array<Order>> = new Cache<Array<Order>>();
   ...
    getActiveOrders(): Observable<Array<Order>> {   // the method should be syncrhonized
       if (this._activeOrdersCache.hasCache()) {
           return of(this._activeOrdersCache.get());
       }

       return this.httpClient.get('/market/orders/active')
        .pipe(
            map((res: any) => {
                return Order.fromJsonArray(res);
            }),
            tap((activeOrders: Array<Order>) => {
                this._activeOrdersCache.set(activeOrders, 5, TimeUnit.MINUTES);
            })
        );
}
Run Code Online (Sandbox Code Playgroud)

但是一些组件同时调用该方法,因此实际上它们都在调用后端(因为缓存无法及时初始化),并且只有在获得响应后,缓存才会填充两次。那么有没有一种方法可以使该服务方法同步(就像在java中一样),使第二个线程等待第一个线程完成,并仅在缓存确定后才开始执行 getActiveOrders 方法?

Angular 是否有类似 Java 或 C# 中的同步机制?

Bas*_*räu 5

不要缓存结果,而是缓存可观察对象本身,并使用shareReplay().

export class CryptoMarketService implements MarketService {
  private _activeOrdersCache: Cache<Observable<Array<Order>>> = new Cache<Observable<Array<Order>>>();

  getActiveOrders(): Observable<Array<Order>> {
    if (!this._activeOrdersCache.hasCache()) {
      const obs = this.httpClient.get('/market/orders/active')
        .pipe(
          ...
          shareReplay(1)
        );
      this._activeOrdersCache.set(obs, 5, TimeUnit.MINUTES);
    }

    return this._activeOrdersCache.get();
  }
}
Run Code Online (Sandbox Code Playgroud)

所有订阅者都将收到相同的可观察值,并且此时流的结果将被共享,这意味着之前的 HTTP 调用和可管道运算符shareReplay()只会运行一次。