rxjs observable:使用某种等待?

问题描述 投票:0回答:2

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

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(?)

javascript angular ionic-framework rxjs
2个回答
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. 同步:使用Angular APP_INITIALIZER(请参阅here)进行后端调用,并确保在应用程序引导时存在用户对象。
  2. 异步:修改现有应用程序以将用户实例存储在某个服务中的RxJs BehaviorSubject中,并且依赖于它的组件在需要用户实例的任何地方都订阅该BehaviorSubject。当服务构造时,让它进行后端调用并在完成时将完成的用户实例粘贴到BehaviorSubjectuserSubject.next(user))中。
© www.soinside.com 2019 - 2024. All rights reserved.