Angular – shareReplay 不缓存数据

Angular – shareReplay not caching data

我有一个 Angular 服务,它应该从后端获取一个大对象并无限期地缓存它。我不想要后续的 HTTP 调用。它看起来像这样:

@Injectable({
    providedIn: 'root'
})
export class SomeService {
    data$: Observable<MyData>;

    constructor(apiService: SomeApiService) {
        this.data$ = of(new MyData()).pipe(
            switchMap(c => apiService.get().pipe(shareReplay(1)))
        )
    }

    // used by a route resolver, which should execute the first (and ONLY) HTTP request:
    get dataLoaded$(): Observable<boolean> { 
        return this.data$.pipe(
            map(d => !!d)
        );
    }
}

认为这样做的是:

  1. 从一个空的 MyData 对象开始,这样应用程序就不会在 HTTP 请求解析之前中断
  2. 切换到 apiService.get() 的结果,一旦它发出,缓存它并使用 shareReplay(1)
  3. 将它变成热 Observable

相反,每次构造使用该服务的组件时,都会发送一个新的 HTTP 调用。

我做错了什么?

shareReplay 位置不对:

您的版本:

constructor(apiService: SomeApiService) {
    this.data$ = of(new MyData()).pipe(
        switchMap(c => apiService.get().pipe(shareReplay(1)))
    )
}

应该怎样

constructor(apiService: SomeApiService) {
    this.data$ = of(new MyData()).pipe(
        switchMap(c => apiService.get()),
        shareReplay(1)
    )
}

这是因为您唯一共享的是 apiService.get() 返回的 observable。因此,如果您有 2 个订阅者 this.data$,它会创建整个流 2 次。

如果您将 shareReplay 移动为整个流的最后一个运算符,那么整个流将被共享,仅强制订阅其上方的所有内容。