rxjs可观察:使用某种等待方式吗?

时间:2019-03-18 16:03:54

标签: javascript angular ionic-framework rxjs

我为HTTP请求添加了一个拦截器,在这里我必须使用用户实例的访问令牌。在我的应用程序组件中,我初始化了用户:

app.component.ts

private async restoreUser(): Promise<UserModel | any> {
   // ... some view stuff

   return this.userService.restore()
      // login instance could be found
      .then(async () => {
         // ... some view stuff
      })

      // local storage is empty -> login is necessary
      .catch(async () => {
         // ... some view stuff

         this.subscription = this.networkSrv.getNetworkStatus()
            .subscribe((status: ConnectionStatus) => {
               if (status === ConnectionStatus.Online) {
                  // ... some view stuff
               } else {
                  // ... some view stuff
               }
            });
      });
}

http.interceptor.ts

return this.userSrv.user.pipe(
   map((user: UserModel) => request.clone(
      {setParams: {'access-token': user.accessToken}}
   )),
   mergeMap(request => next.handle(request))
);

现在,我想通过初始化我的应用程序来发出请求。问题是,用户实例为空,应用程序引发错误。有没有办法像await->这样来设置用户实例?

示例:

this.transmissionSrv.restoreQueue().then((projects: ProjectModel[]) => {
   this.transmissionSrv.transmitProjects(projects, true).subscribe(console.log);
});

当前,我使用setTimeout方法,但这不是我应该这样做的方法,对吗?另外,对使用Observer不一致表示抱歉;离子经常使用Promises(?)

2 个答案:

答案 0 :(得分:1)

您应该尝试在地图之前添加过滤器。使用过滤器,您的地图只有在设置了用户之后才会被呼叫。

return this.userSrv.user.pipe(
   filter(Boolean),
   map((user: UserModel) => request.clone(
      {setParams: {'access-token': user.accessToken}}
   )),
   mergeMap(request => next.handle(request))
);

答案 1 :(得分:1)

有两种方法可以解决此问题。

  1. 同步:使用角度APP_INITIALIZER(请参阅here)进行后端调用,并确保在应用程序引导时存在用户对象。
  2. 异步地:修改现有应用程序,以将用户实例存储在某处服务中的RxJs BehaviorSubject中,并使依赖它的组件在需要用户实例的任何地方订阅该BehaviorSubject。服务构造完成后,让它进行后端调用,并在完成后将完成的用户实例粘贴在BehaviorSubjectuserSubject.next(user))中。