【问题标题】:Wrapping rxjs observable to do something before and after (for example show/hide loading screen)包装 rxjs observable 在前后做一些事情(例如显示/隐藏加载屏幕)
【发布时间】:2021-01-10 02:33:59
【问题描述】:

我正在尝试创建包装给定 Observable 并向其添加加载屏幕的函数。
函数function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> 应该像这样工作:

  1. 显示加载屏幕。
  2. 执行作为参数接收的 observable
  3. 在发出所有值后隐藏加载屏幕。

我最初的实现想法是:

function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> {
  return of(null).pipe(
    tap(() => console.log("show loading screen")),
    switchMap(() => obs$),
    finalize(() => console.log("hide loading screen"))
  );
}

但是当我将其他运算符链接到此函数的结果时,“隐藏加载屏幕”会在这些链接之后执行(而不是在原始可观察完成之后)。

这里是一个例子:https://stackblitz.com/edit/rxjs-wrapping-observable

上面控制台中的结果是

show loading screen
im reducing
im reducing
reducing finished so loading screen should be hidden
the result is 6
hide loading screen

我的目标应该是什么

show loading screen
im reducing
im reducing
hide loading screen
reducing finished so loading screen should be hidden
the result is 6

【问题讨论】:

    标签: typescript rxjs rxjs6


    【解决方案1】:

    这是因为finalize 在拆解后执行,请参阅此GitHub Issue 了解更多信息。这意味着即使您在链的中间使用finalize,即使在reducemergeMap 之前,它也会在拆卸过程中最后执行。

    至于您的问题的替代解决方案,您可以像这样使用tap

    function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> {
      return of(null).pipe(
        tap(() => console.log("show loading screen")),
        switchMap(() => obs$),
        tap(
          () => {},
          () => console.log("hide loading screen"),
          () => console.log("hide loading screen")
        ),
      );
    }
    

    除了next 回调,您还可以向tap 运算符提供errorcomplete 回调。有关错误和完成回调的更多信息,请参阅RxJS Tap Doc

    【讨论】:

    • 不知道您可以点击 onError 和 onComplete。谢谢,完美运行。
    猜你喜欢
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    相关资源
    最近更新 更多