如何一个接一个地订阅 Observable

How to subscribe Observable after another one

我想在登录后获取当前登录用户但是this.router.navigate([this.returnUrl]);不是 运行 : 我在这里错了什么以及我可以解决这个问题

onSubmit(): void {
    this.authService.login(this.loginForm.value).subscribe(next => {
    }, error => {
      this.alertService.error(error.error);
    }, () => {
      this.authService.getCurrentUser().subscribe(u => localStorage.setItem('role', u.role), error => {
        this.alertService.error(error.error);
      }, () => {
        this.router.navigate([this.returnUrl]);
      });
    });
  }

一个好的做法是使用 mergeMap 链接 API 调用,如下所示:

onSubmit(): void {
    this.authService.login(this.loginForm.value).pipe(
        mergeMap(() => this.authService.getCurrentUser()),
        catchError(err => this.alertService.error(err.error)),
        finalize(() => this.router.navigate([this.returnUrl]))
    ).subscribe(u => {
        localStorage.setItem('role', u.role);
    });
}

另请注意,我直接在管道中添加了一个 catchError,但您也可以在订阅中捕获错误,如下所示:

onSubmit(): void {
    this.authService.login(this.loginForm.value).pipe(
        mergeMap(() => this.authService.getCurrentUser())
    ).subscribe(
        u => localStorage.setItem('role', u.role),
        err => this.alertService.error(err.error),
        () => this.router.navigate([this.returnUrl])
    );
}

您的代码中的另一件重要事情是您将导航放在 finally 块中,这意味着您将在成功 错误的情况下重定向。这就是我在第一个示例中放置 finalize 的原因。如果路由是 only 成功,代码应该是:

onSubmit(): void {
    this.authService.login(this.loginForm.value).pipe(
        mergeMap(() => this.authService.getCurrentUser()),
        catchError(err => this.alertService.error(err.error))
    ).subscribe(u => {
        localStorage.setItem('role', u.role);
        this.router.navigate([this.returnUrl]);
    });
}

onSubmit(): void {
    this.authService.login(this.loginForm.value).pipe(
        mergeMap(() => this.authService.getCurrentUser())
    ).subscribe(
        u => {
            localStorage.setItem('role', u.role);
            this.router.navigate([this.returnUrl]);
        },
        err => this.alertService.error(err.error)
    );
}