RxJs catchError 改变 return 类型

RxJs catchError changes return type

我正在尝试实现一些缓存,并且我有以下方法。 catchError 块导致错误,因为 return 类型变为 Observable<Client | Client[]>。我不明白为什么它认为它不是客户端数组,或者如何修复。

#clients: Client[] = []
#clientsLastModified: string | null = null


index(): Observable<Client[]> {
    let headers = new HttpHeaders()
    if (this.#clientsLastModified)
        headers = headers.set('If-Modified-Since', this.#clientsLastModified)

    return this.http.get<IClientDTO[]>('clients', {headers, observe: 'response'}).pipe(
        map(x => {
            this.#clientsLastModified = x.headers.get('Last-Modified')

            if (x.status === HttpStatusCode.Ok && x.body) {
                this.#clients = x.body.map(x => new Client(x))
                return this.#clients
            } else
                return of([])
        }),
        catchError((err: unknown) => {
            if (err instanceof HttpErrorResponse && err.status === HttpStatusCode.NotModified)
                return this.#clients

            return throwError(() => err)
        })
    )
}

要更正此问题,需要进行两个小更改:

  1. 不要在地图中使用 of。您希望地图的结果为 return 类型 Client[]of 成为 return Observable<Client[]>

  2. catchError 中使用 of。在 catchError 内,您应该 return 可观察,因此需要 of。没有显示错误的原因是因为类型是 Array,而 Array 也是一个 vaild ObservableInput,但会有不同的行为。 RxJS 会将 Array 转换为单独发出每个项目的可观察对象(因此类型最终为 Observable<Client> 而不是 Observable<Client[]>)。

return this.http.get<IClientDTO[]>('clients', {headers, observe: 'response'}).pipe(
  map(x => {
    this.#clientsLastModified = x.headers.get('Last-Modified')

    if (x.status === HttpStatusCode.Ok && x.body) {
      this.#clients = x.body.map(x => new Client(x))
        return this.#clients
      } else
        return [] // <-- don't use of
  }),
  catchError((err: unknown) => {
    if (err instanceof HttpErrorResponse && err.status === HttpStatusCode.NotModified)
      return of(this.#clients) // <-- use of

      return throwError(() => err)
  })
)