首页 > 解决方案 > 角度exhausMap问题?

问题描述

我有登录方法,需要在将其移至下一页之前进行两次调用。第一种方法调用登录 api 并返回令牌。我将此令牌保存到 localStorage 并从标头拦截器中获取。第二次调用返回用户名和显示名,当完成两个调用时,我将用户路由到登录页面。

我认为两次调用 exhausMap 的最佳解决方案,但我以前没有使用过,我不知道如何在 exausm 映射中合并这两种方法。如果有人可以为此编写语法。

提前致谢。

这是方法:

login(type: string, email: string, password: string): Observable<any> {
        this.url = '';
        const reqUrl = `${environment.api_url}${'users/logins'}`;
        this.url = `${reqUrl}`;

        return this.post(
            {
                type,
                profile: { email, password },
            }).pipe(
                catchError(this.errorHandlerService.handleError),
                tap(response => {
                    console.log('1', response);
                    this.storageService.saveToken(response.accessToken);
                }));

        this.userService.getUserInfo()
            .pipe(
                catchError(this.errorHandlerService.handleError),
                tap(response => {
                    this.handleAuthentication(
                        response.email,
                        response.displayName
                    );
                    console.log('2', response.displayName);
                })
            );
    }

    private handleAuthentication(email: string, displayName: string): void {
        const user = new User(email, displayName);
        this.user.next(user);
        this.storageService.saveUser(user);
    }

标签: angulartypescript

解决方案


可观察对象的伟大之处在于,您可以将它们链接在一起形成一个流畅的动作:

  login(type: string, email: string, password: string): Observable<any> {
    const reqUrl = `${environment.api_url}${'users/logins'}`;
    this.url = `${reqUrl}`;

    const profile = { email, password };
    return this.post({ type, profile }).pipe(
      exhaustMap(response => {
        console.log('1', response);
        this.storageService.saveToken(response.accessToken);

        return this.userService.getUserInfo().pipe(
          tap(response => {
            this.handleAuthentication(
              response.email,
              response.displayName
            );
            console.log('2', response.displayName);
          })
        )
      }),
      catchError(this.errorHandlerService.handleError),
    );

  }

在这里,我们调用 post 可能使用 Angular 的 HttpClient's post,它返回一个以响应完成的可观察对象。然后我们使用exhaustMap将 http 调用的源 observable 投影到另一个调用。我们也可以switchMap在这里使用,但是exhaustMap 可以确保第一个帖子完成。

请注意,如果this.post没有完成,exhaustMap 将阻止它发出。


推荐阅读