RxJs Observable forkJoin

时间:2018-05-01 15:24:06

标签: angular rxjs

我正在Angular 5(RxJs 5.5.1)中编写服务,我有以下场景,我正在尝试实现登录工作流程。

...
signInBasic(user: string, pwd: string): Observable<AuthenticationStatus> {
    return this.http.post('some_url', params, { observe: 'response', responseType: 'text' })
      .map((response: HttpResponse<Object>) => {
        this.status = response.status === 200 ? AuthenticationStatus.Authenticated : AuthenticationStatus.NotAuthenticated;
        return this.status;
      })
      ...
      /* HERE */
      ...

}

getPrimaryInfo(): Observable<any> {}
getPermissions(): Observable<any> {}
...

/* HERE */点,取决于this.status值(具体为Authenticated),我想再发出两个HTTP请求(通过getPrimaryInfogetPermissions方法),以便从后端获取一些用户的详细信息。完成后,我想返回this.status作为signInBasic方法的返回值。如果用户未经过身份验证,我将会返回this.status AuthenticationStatus.NotAuthenticated值,因为之前已设置此值。

我期待forkJoin,但我不明白只有当这两个HTTP调用完成时我才能返回一些内容。

2 个答案:

答案 0 :(得分:2)

您可以使用concatMap等待forkJoin完成,然后将结果映射到this.status,无论这两个请求返回了什么。

signInBasic(user: string, pwd: string) {
  return this.http.post('some_url', params, ...)
    .concatMap((response: HttpResponse<Object>) => {
      this.status = response.status === 200 ? AuthenticationStatus.Authenticated : AuthenticationStatus.NotAuthenticated;

      if (this.status === AuthenticationStatus.Authenticated) {
        return forkJoin(getPrimaryInfo(), getPermissions())
          .pipe(
            map(() => this.status),
          );
      } else {
        return of(this.status);
      }
    });
}

答案 1 :(得分:0)

在这种情况下,

带有投影功能的switchMap是你的朋友:

return this.http.post('some_url', params, { observe: 'response', responseType: 'text' })
  .map((response: HttpResponse<Object>) => {
    this.status = response.status === 200 ? AuthenticationStatus.Authenticated : AuthenticationStatus.NotAuthenticated;
    return this.status;
  })
  .switchMap(status => (status === AutheticationStatuses.Authenticated)
                          ? forkJoin(getPrimaryInfo(), getPermissions())
                          : of(null),
             (status, inner) => status);