Resolve不会等到API调用完成后再落到函数结尾

时间:2017-10-27 15:08:50

标签: angular angular-router

我正在制作一个Angular 4网络应用。我有一个页面,需要在显示之前等待数据,所以我正在使用解决方案。首先解析检查数据是否在存储中可用,是否检查路由和数据中的ID是否匹配,如果不匹配,则从API检索数据,最后如果存储中不存在数据则从API检索数据。但是,如果进行API调用,函数总是落到最后。我做错了什么?

resolve(route: ActivatedRouteSnapshot): Observable<PDataInterface>
{
  const routeID = route.params.id;
  // get data from storage
  this.getData();
  if (!!this.pData) {
    if (this.pData.id == routeID) {
      return Observable.of(this.pData);
    } else {
      this.API.getInfo(this.routeID).subscribe((data) => {
        this.pData = data;
        return Observable.of(this.pData);
      });
    }
  } else {
    this.API.getInfo(this.pData.id).subscribe((data) => {
      this.pData = data;
      return Observable.of(this.pData);
    });
  }
  // function always comes here if API calls are made
  console.log("failed resolve");
  this.router.navigate(['/dashboard']);
}

api.ts

getInfo(id) {
    const URL = `${this.API}/paintline/${id}`;
    return this.refreshToken()
      .flatMap(() => this.authHttp.get(URL, this.headers))
      .map((response: Response) => response.json().data)
      .share()
      .catch(this.handleError);
}

这是refreshToken()中调用的getInfo()。如果我的JWT令牌在向后端

发出请求之前已过期,则会刷新它
refreshToken(): Observable<any>
{
  const URL = `${this.API}/refresh?token=${this.token}`;
  if (this.jwtHelper.isTokenExpired(this.token)) {
    return this.authHttp.get(URL)
      .map((rsp) =>
        {
          this.setToken(rsp.json().token);
          this.authNotifier.next(true);
          return rsp.json().token;
        },
        err =>
        {
          this.authNotifier.next(false);
          this.logout();
          console.log(err);
        })
      .share();
  }
  else { return Observable.of(this.token); }
}

app.module.ts

RouterModule.forRoot([
{
        {
          path: 'details',
          component: PDetailsComponent,
          resolve: {pData: PResolverService}
        },
}]

1 个答案:

答案 0 :(得分:2)

当您订阅api时,您的API将被触发,但其余的解析代码将继续执行。这就是为什么它一直达到你的console.log("failed resolve");。相反,你应该返回api observable并让解析器进行订阅。

resolve(route: ActivatedRouteSnapshot): Observable<PDataInterface>
{
    const routeID = route.params.id;
    // get data from storage
    this.getData();
    if (!!this.pData) {
        if (this.pData.id == routeID) {
            return Observable.of(this.pData);
        } else {
            return this.API.getInfo(this.routeID);
        }
    } else {
        return this.API.getInfo(this.pData.id);
    }
}