如何将角度API转换为同步API

时间:2017-11-02 10:04:34

标签: angular rxjs

我需要对REST服务进行连续的http调用,但是每个调用都在调用头中使用唯一的有效令牌,所以如果我有一些组件同时初始化它们正在“获取” “同时使用相同的令牌调用,因此我需要修改我的get函数以进行一次调用,等待响应,从该响应中获取新令牌并在下次调用中使用它等等接下来的电话。

我的自定义http服务

    @Injectable()
    export class HttpCustomService {

    token: string;
    activeRequestsSubject = new BehaviorSubject<number>(0);
    constructor(private httpClient: HttpClient,
              private authService: AuthService) {

       this.authService.token$.subscribe(
       token => this.token = token
       );
    }

    getHeaders( withToken: boolean) {
    let headers = new HttpHeaders({'Content-Type': 'application/json; 
    charset=UTF-8', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache' });
    if (withToken) {
        headers = new HttpHeaders({'Content-Type': 'application/json; charset=UTF-8',
                  'Authorization': `Bearer ${this.token}`, 
                  'Cache-Control': 'no-cache', 'Pragma': 'no-cache'} );
    }

    return headers;
  }

  get(url: string, withToken: boolean): Observable<any> {
      this.loadingSubject.next(true);
      const options = {
      headers: this.getHeaders(withToken)
    };
    this.incrementActiveRequest();
    return this.httpClient.request('get', url, options).do(
      response => {
        if (response.body && response.body.token) {
          this.authService.setToken(response.body.token);
        }
        this.loadingSubject.next(false);
        this.decrementActiveRequest();
      },
      error => {this.loadingSubject.next(false);
                this.decrementActiveRequest();
      });
  }

这些是我如何使用该服务的示例

getQuotes(): Observable<any> {
    return this.httpCustom.get(`${this.urlBase}/quotes`, true)
        .map((response: any) => {
            return response.body.result;
        }).catch(err => {
            this.handleError(err);
            return Observable.of(null);
        });
}

getPolicies(): Observable<any> {
    return this.httpCustom.get(`${this.urlBase}/policies`, true)
        .map((response: any) => {
            return response.body.result;
        }).catch(err => {
            this.handleError(err);
            return Observable.of(null);
        });
}

我想我必须使用flatMap,但我不知道如何在我的“get”方法中使用它。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

我可能误解了,但认为变化很小

  

每次通话都使用唯一的有效令牌

所以你不想在构造函数中使用它,

constructor(private ...) {
  this.authService.token$.subscribe(token => this.token = token);
}

你想在每次获取时先做到这一点,

get(url...) {
  this.authService.token$.map(token => {
    const headers = this.getHeaders(token);
    ...
    this.httpClient.request(...)
  });
}

如果是单次拍摄,你需要在authService中保存令牌吗?

另外,我认为上面activeRequestsSubjectloadingSubject

的变量相同

修改 在OP发表评论后进行更正 - 将this.authService.token$.subscribe更改为this.authService.token$.map

答案 1 :(得分:0)

我显然找到了解决方案。感谢所有评论,他们都以某种方式帮助了我。

我的新方法:

get(url: string): Observable<any> {
if (this.activeRequestsSubject.value === 0) {
  this.incrementActiveRequest();
  const headers = {headers: new HttpHeaders({'Content-Type': 'application/json; charset=UTF-8',
                                              'Authorization': `Bearer ${this.token}`,
                                              'Cache-Control': 'no-cache',
                                              'Pragma': 'no-cache'})};
  return this.httpClient.request('get', url, headers)
                          .do(res => {
                            this.decrementActiveRequest();
                            this.authService.setToken(res['token']);
                            return res; });
}else {
  this.incrementActiveRequest();
  return this.authService.token$.skip(this.activeRequestsSubject.value - 2).first().mergeMap(
     (token: string) => {
      const headers = {headers: new HttpHeaders({'Content-Type': 'application/json; charset=UTF-8',
                                                  'Authorization': `Bearer ${token}`,
                                                  'Cache-Control': 'no-cache',
                                                  'Pragma': 'no-cache'})};
      return this.httpClient.request('get', url, headers).do(res => {
                                                                    this.decrementActiveRequest();
                                                                    this.authService.setToken(res['token']);
                                                                    return res; });
      }
     );
}

}