RxJs 2 Observables:取第一个$否则第二个$如果为空

RxJs 2 Observables: Take first one$ else second$ if empty

(仅供参考:Angular+打字稿)

我有一个函数需要 return 廉价 Observable 1 如果它有任何东西,否则昂贵 Observable 2

我使用 Race 来选择更快的一个,但这并不理想,因为 http 调用开始然后被终止。

get(): Observable<Cat> {
    let cachedValues$ = (gets from fast cache)
    let serverValues$ = (gets from expensive server)
    return race(cachedValues$, serverValues$);
}

我想这行得通:

get(): Observable<Cat> {
   let serverValues$ = (gets from expensive server)
   let cachedValues$ = (gets from fast cache);

   return cachedValues$.pipe(
      switchMap(value => {
        return value ? of(value) : serverValues$;
      })
   );

}

尝试使用 switchMap...我假设您拥有的是伪代码。

这将尝试从 cachedValues observable 获取,如果结果为假,它将 returnserverValues observable。否则,它将 return 缓存结果包装为一个可观察对象,因为 switchMap 必须 return 一个可观察对象。

import { of } from 'rxjs'

const cachedValues$ = fastObservable;
const serverValues$ = slowObservable;

return cachedValues$.pipe(
  switchMap(cacheHit => {
     if (!cacheHit) {
       return serverValues$;
     }
     
     return of(cacheHit);
  })
)

您可以使用 concat 来设置一系列可观察值。假设您的每个源将发出一个结果然后完成,您可以通过管道传递给 find 运算符,条件是值不为空。

Find 将 return 第一个通过谓词的发射然后完成。它与 firsttake(1) 的独特之处在于,如果从未满足条件,则最后的结果将 returned 所以你总能得到结果。

get(): Observable<Cat> {
    let cachedValues$ = (gets from fast cache)
    let serverValues$ = (gets from expensive server)
    return concat(cachedValues$, serverValues$).pipe(find(x => !!x));
}

如果您的 cache$ 是一个值为 1 或 0 的 Observable,您可以

return cache$.pipe(
    first(),
    catchError(() => server$),
);

如果您的 cache$ 已经 return 一个没有值的错误,则您不需要 first() 运算符。