Angular RxJS 顺序请求问题

Angular RxJS sequential requests issue

我有以下要求;

  public userLogin(username: string, password: string) {
    return this.http.post<any>(`${this.apiURL}/login `, {username, password}, constants.httpOptions)
      .pipe(
        map((response) => {
          this.setToken(response.token);
        })
      );
  }

  public getUser() {
    return this.http.get<IUser>(`${this.apiURL}/api/account`)
      .pipe(
        map((user: IUser) => {
          sessionStorage.setItem('user', JSON.stringify(user));
          this.userSubject.next(user);
        })
      );
  }

我想依次调用它们并检查最后一个请求的返回值。 然而,我实现了以下代码块,console.log 输出是 subscribe 部分中的 undefined。 在网络选项卡中,我可以看到两个请求都是按顺序调用的,没有错误。

this.authService.userLogin(username, password).pipe(
        concatMap(() => { return this.authService.getUser() })
      ).subscribe((res: any) => {
        console.log(res);
        this.router.navigate(['/home']);
      }, (err: HttpErrorResponse) => {
        if (err.status === 401) {
          console.log('sign-in page - 401');
          this.unauthorized = true;
        }
      });

我做错了什么?

您的 getUser Observable 上的 map 运算符没有 return 任何东西。让它 return Observable 应该发出什么,你会在响应中得到一些东西。

此外,将逻辑放在 subscribe 回调中并不是最佳做法。使用 tap 实现副作用。

这是在 TypeScript 中指定 return 类型的一个很好的例子。如果你有,你会意识到 map 运算符在 getUser 中的结果总是未定义的。在这种情况下,我认为您想使用 tap,它允许您在进一步通过流传递源发射的同时执行副作用。

public getUser(): Observable<IUser> {
  return this.http.get<IUser>(`${this.apiURL}/api/account`).pipe(
    tap((user: IUser) => {
      sessionStorage.setItem('user', JSON.stringify(user));
      this.userSubject.next(user);
    })
  );
}

如果您打算 return 从中获取令牌值,您可能还想在 setToken 中使用 tap方法。