首页 > 解决方案 > Rxjs 链接,怎么做?

问题描述

以下代码是我所拥有的并且它有效。

canActivate(route: ActivatedRouteSnapshot): Observable<UrlTree | boolean> {
  return new Observable<UrlTree | boolean>((observer) => {
    this._authorizedStore
      .select(selectProfile)
      .pipe(take(1))
      .subscribe((profile) => {
        if (!profile) {
          this._authorizedStore.dispatch(
            AuthorizedActions.loadProfile({ userId: this._authenticationApi.getUser().id }),
          );
        }

        this._authorizedStore
          .select(selectAuthorizedState)
          .pipe(first((state) => !!state.profile))
          .subscribe((state) => {
            if (state.profile.profiles.length > 0) {
              observer.next(true);
            } else {
              observer.next(this.router.createUrlTree(['./settings']));
            }
            observer.complete();
          });
      });
  });
}

我想要的是找出一种更好、更漂亮的方法来做同样的事情。基本上我想先检查我是否有个人资料,如果没有,我想触发请求然后等待。需要注意的一件事,正如您所看到的,我正在使用 Ngrx,所以如果我在开始时不采取(1),我会得到一个无限循环(不是配置文件,发出请求,不是配置文件,发出请求......) .

有任何想法吗?

标签: angulartypescriptrxjs

解决方案


您可以使用tapswitchMap。像这样:

this._authorizedStore
  .select(selectProfile)
  .pipe(
    take(1),
    tap(profile => {
      if (!profile) {
        this._authorizedStore.dispatch(
          AuthorizedActions.loadProfile({ userId: this._authenticationApi.getUser().id }),
        );
      }
    }),
    switchMap(profile => this._authorizedStore.select(selectAuthorizedState).pipe(first(state => !!state.profile)))
  )
  .subscribe(state => {
    if (state.profile.profiles.length > 0) {
      observer.next(true);
    } else {
      observer.next(this.router.createUrlTree(['./settings']));
    }
    observer.complete();
  });

您还可以将整个代码缩短为:

canActivate(route: ActivatedRouteSnapshot): Observable<UrlTree | boolean> {
  return this._authorizedStore
    .select(selectProfile)
    .pipe(
      take(1),
      tap(profile => {
        if (!profile) {
          this._authorizedStore.dispatch(
            AuthorizedActions.loadProfile({ userId: this._authenticationApi.getUser().id }),
          );
        }
      }),
      switchMap(profile => this._authorizedStore.select(selectAuthorizedState)),
      first(state => !!state.profile),
      map(state => state.profile.profiles.length > 0 ? true : this.router.createUrlTree(['./settings']))
    );
}

推荐阅读