Angular Rxjs 管理嵌套订阅

问题描述 投票:0回答:2

嗨,我有一个具有嵌套订阅的函数。

  public loadUser(): Observable<string> {
    return this.getUser().subscribe(
      (userResponse: any) => {
        if (userResponse) {
          this.userId = userResponse.toLowerCase();
          this.getAppSupportUsersList();
          this.getUserEntitlements().subscribe((response: any) => {
            localStorage.setItem('UserEntitlements', JSON.stringify(response));
            this.processUIEntitlements(response);
            this.getUserDetails(this.userId).subscribe((userDetails) => {
              this.userInfo = userDetails;
              this.setUserName();
            });
          });
        }
      },
      (error) => {
        console.error(error);
      }
    );
  }

我不确定如何避免订阅嵌套。有没有更好的方法使用

switchMap()
mergeMap()
重写嵌套订阅?

angular rxjs rxjs6
2个回答
2
投票

这可以用 rxjs switchMapmap 重写,具体取决于您想要如何处理多个请求。

如果仅计算最新的计数(这似乎是自您写入本地存储以来最指示的计数),请采用

switchMap
方法。

public loadUser(): Observable<string> {
  return this.getUser().pipe(
    filter(val => !!val),
    switchMap(userResponse => {
      this.userId = userResponse.toLowerCase();
      this.getAppSupportUsersList();
      return this.getUserEntitlements();
    }),
    switchMap(response => {
      localStorage.setItem('UserEntitlements', JSON.stringify(response));
      this.processUIEntitlements(response);
      return this.getUserDetails(this.userId);
  }).subscribe({
    next: (userDetails) => {
      this.userInfo = userDetails;
      this.setUserName();
    },
    error: (error) => console.log(error)
  })
}     

1
投票

我们可以使用

switchMap
,因为我们只想链接订阅,在前一个完成后切换到另一个。此外,我们需要将订阅添加到订阅并在销毁时取消订阅以避免内存泄漏!

  public loadUser(): Observable<string> {
    return this.getUser().pipe(
      switchMap((userResponse: any) => {
        if (userResponse) {
          this.userId = userResponse.toLowerCase();
          this.getAppSupportUsersList();
          return this.getUserEntitlements().pipe(
            switchMap((response: any) => {
              localStorage.setItem('UserEntitlements', JSON.stringify(response));
              this.processUIEntitlements(response);
              return this.getUserDetails(this.userId).pipe(
                tap((userDetails) => {
                  this.userInfo = userDetails;
                  this.setUserName();
                })
              )
            })
          );
        }
        return of(null);
      })
    );
  }

  callingFunction() {
      this.loadUser().subscribe({
        next: (next) => {
          console.error(next);
        },
        error: (error) => {
          console.error(error);
        }
      });
  }
© www.soinside.com 2019 - 2024. All rights reserved.