【问题标题】:Dependent HTTP calls in angular service角度服务中的依赖 HTTP 调用
【发布时间】:2020-04-18 11:20:41
【问题描述】:

我正在从 Angular 服务调用安全的 REST API。在这种情况下,我必须在调用任何 API 之前获取一次令牌,并将其作为 HTTP Header 的一部分传递。但是,当我从我的组件中调用任何函数时,我将 app_token 设为未定义。这是由于对 token_api 的异步调用。下一个调用成功,因为之前的调用从服务器获取令牌的值。

我已经在 get_token 函数中添加了 async-await,但徒劳无功.. 关于如何处理这种情况的任何建议。

private app_token;

private getToken(){    
    if (this.token == undefined) {
      console.log("getting new token");
      return this.httpClient.post<Token>(this.TOKEN_API, body, options)
        .pipe(retry(3), catchError(this.handleError))
        .subscribe(data => {
            console.log(data[0].username);
            return this.app_token = data;
        });
    }
}

public getEmployee{
    this.getToken();

    const headers = new HttpHeaders()
      .set('Authorization', 'Bearer ' + this.app_token );

    const options = {
      headers: headers
    };

    return this.httpClient.get(this.EMP_API, options)
      .pipe(retry(3), catchError(this.handleError));
}

public getDepartments{
    this.getToken();

    const headers = new HttpHeaders()
      .set('Authorization', 'Bearer ' + this.app_token );

    const options = {
      headers: headers
    };

    return this.httpClient.get(this.DEPT_API, options)
      .pipe(retry(3), catchError(this.handleError));
}

【问题讨论】:

    标签: angular httpclient angular-httpclient


    【解决方案1】:

    使用 toPromise()getToken() 的 observable 转换为 promise:

    private getToken(){    
        if (this.token == undefined) {
          console.log("getting new token");
          return this.httpClient.post<Token>(this.TOKEN_API, body, options)
            .pipe(retry(3), catchError(this.handleError))
            .subscribe(data => {
                console.log(data[0].username);
                return this.app_token = data;
            })
            .toPromise();
        }
    }
    

    现在您可以轻松地使用 async/await 来实现此功能

    public async getEmployee{
        await this.getToken();
    
        const headers = new HttpHeaders()
          .set('Authorization', 'Bearer ' + this.app_token );
    
        const options = {
          headers: headers
        };
    
        return this.httpClient.get(this.EMP_API, options)
          .pipe(retry(3), catchError(this.handleError));
    }
    

    注意:如果getToken()获取令牌失败,请处理错误。

    【讨论】:

    • 1) 他们已经在 observable 上完成了subscribe,所以这是订阅,而不是 observable。你不能对订阅做 toPromise。 2)为什么无论如何都要将一个可观察对象转换为一个承诺? Observables 比 Promise 更强大
    • 毫无疑问 Observable 比 Promise 更强大。但是在使用了很多 Promise 以及“async/await”的语法糖之后,我想知道 Angular 团队放弃 Promise 转而支持 Observables 是否是一个明智的决定。使用 async-await 精心设计的代码更容易维护。所以我再次赞成这个答案。这个想法很好,尽管我不得不承认执行可能很差。结合 subscribe()toPromise() 对我来说似乎是个坏主意。
    【解决方案2】:

    最后,我找到了解决这个问题的方法。在这里,我使用 RxJS Pipe 和 concatMap 函数来执行 2 个 http 请求并将一个请求的输出传递给另一个请求。

      return this.getToken().pipe(
        concatMap((tokenData)=> {
          headers = headers.append('Authorization', 'Bearer ' + this.token.access_token);
    
          return this.httpClient.get(url, { headers: headers })
            .pipe( retry(3), catchError(this.handleError));
        })
      );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-01
      • 2018-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多