Angular 7-如何在进行其他API调用之前强制API调用等待HTTPInterceptor完成?

在Angular 7中,我使用HttpInterceptor来获取Bearer令牌,该令牌需要作为标头添加到任何API调用中(例如getOnLoadData())。每当我尝试进行getOnLoadData()调用时,拦截器都会成功调用,但是令牌值会继续返回null,因为令牌值在拦截器完成之前就已执行。

我正在尝试使用async / await来使调用异步,但是看起来我做错了,而且似乎无法弄清楚错误出在哪里。我是Angular的新手。我搜索了很多不同的示例,但无法弄清楚。

HTTP拦截器

intercept(req: HttpRequest<any>, next: HttpHandler) {
    return from(this.handle(req, next))
  }

  async handle(req: HttpRequest<any>, next: HttpHandler) {
    const result = await this.getBearerToken();

    const tokenizedReq = req.clone({
      setHeaders: {
        Authorization: `Bearer ${result}`
      }
    })

    return next.handle(tokenizedReq).toPromise();
  }

API调用

async getOnLoadData() {
    await this.tokenInterceptorService.getBearerToken()

    return this.httpClient.get('/initialloaddata', {
      headers
    });
  }
评论
  • 布水风
    布水风 回复

    您需要创建一个数据流,该数据流从获取auth令牌开始,并在需要时以修补请求结束。

    public intercept(request: HttpRequest<void>, next: HttpHandler): Observable<HttpEvent<void>> {
        return from(this.getBearerToken()).pipe(
            switchMap(token =>
                iif(
                    () => !token,
                    of(request),
                    of(
                        request.clone({
                            setHeaders: {
                                'Authorization': `Bearer ${token}`,
                            },
                        }),
                    ),
                ),
            ),
            switchMap(clonedRequest => next.handle(clonedRequest)),
        );
    }
    

    from knows how to transform a promise to an observable data stream. so it solves it and passes the result (token) to the pipe. then we have switchMap which check whether token is present. If no (iif operator) it returns the original request with no changes (2nd argument of iif), if yes then it returns a clone with the desired header. After that we have one more switchMap that simply switches the data stream to the next.handler.