RxJS-有条件地在管道中添加可观察的对象

时间:2020-09-28 02:34:22

标签: javascript angularjs typescript rxjs

所以我有如下功能

showLoader = () => <T>(source: Observable<T>) => {
  LoaderService.loadPage.next(true);
  return source.pipe(
    finalize(() => {
        LoaderService.loadPage.next(false);
    })
  );
};

然后我在进行如下所示的HTTP调用时使用它

return this.http.get(url).pipe(showLoader())

但是,假设我遇到了这样一种情况:根据条件我需要装载机或任何可观察到的东西;像下面这样

const loader : boolean = false
return this.http.get(url).pipe(concat(...), loader ? showLoader() : of(values))

我尝试使用iif运算符,如下所示

const loader : boolean = false
    return this.http.get(url).pipe(concat(...), mergeMap(v => iif(() => loader, showLoader(), of(v))))

并出现以下错误

TS2345:类型为“(源:可观察)=>可观察”的参数 不能分配给'SubscribableOrPromise <{}>'类型的参数。

有人可以帮助我了解我要去哪里以及如何纠正该问题

2 个答案:

答案 0 :(得分:2)

您可以这样做:

showLoader = (show: boolean = true) => <T>(source: Observable<T>) => {
  if (!show) { // just go straight to source
    return source;
  }

  return defer(() => { // defer makes sure you don't show the loader till actually subscribed
    LoaderService.loadPage.next(true);
    return source.pipe(
      finalize(() => {
        LoaderService.loadPage.next(false);
      })
    )
  })
};

使用:

return this.http.get(url).pipe(showLoader(false))

但是您将来似乎会以静态方式访问LoaderService一系列设计问题和错误。仅供参考。

答案 1 :(得分:1)

我建议类似以下内容:

const startWithTap = (callback: () => void) =>
  <T>(source: Observable<T>) => of({}).pipe(
    startWith(callback),
    switchMap(() => source)
  );

const showLoader = () => <T>(source: Observable<T>) => concat(
  iif(
    () => loader,
    source.pipe(
      startWithTap(() => LoaderService.loadPage.next(true)),
      finalize(() => {
        LoaderService.loadPage.next(false);
      })
    ),
    EMPTY
  ), source);

return this.http.get(url).pipe(
  showLoader()
);