首页 > 解决方案 > 包装 rxjs observable 在前后做一些事情(例如显示/隐藏加载屏幕)

问题描述

我正在尝试创建包装给定 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

标签: typescriptrxjsrxjs6

解决方案


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

至于您的问题的替代解决方案,您可以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回调之外,您还可以向操作员提供errorcomplete回调tap。有关错误和完成回调的更多信息,请参阅RxJS Tap Doc


推荐阅读