首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法使用服务实例调用可注入函数。参数值始终为空。

无法使用服务实例调用可注入函数。参数值始终为空。
EN

Stack Overflow用户
提问于 2020-06-12 01:10:30
回答 1查看 26关注 0票数 0

我有一个角度的网页应用程序,使用访问令牌,可以过期。当它们过期时,401状态响应被发送回应用程序,然后由retryWhen操作符处理。进行令牌刷新api调用的逻辑已放置在我在providers数组@NgModule(中声明的可注入函数中。

该函数如下所示:

代码语言:javascript
运行
复制
{ provide: 'tokenExpired', useValue: ({
  maxRetryAttempts = 1,
  loginService
}: {
  maxRetryAttempts?: number,
  loginService?:LoginService
} = {}) => (attempts: Observable<any>) => {
  return attempts.pipe(
    concatMap((error, i) => {
      const retryAttempt = i + 1;
      if((error && error.headers && (!error.headers.get("reason-unauthorized") || !(error.headers.get("reason-unauthorized") === "authentication-token-expires-soon"))) || retryAttempt > maxRetryAttempts) {
        return throwError(error);
      }
      loginService.requestNewToken().subscribe(success => {
        console.log(
          `Attempt ${retryAttempt}: retrying in ${1000}ms`
        );
        return timer(50);
      }, 
      error => throwError(error));
    })
  );
} },

它基于我在这里发现的教程https://www.learnrxjs.io/learn-rxjs/operators/error_handling/retrywhen,只有作者将逻辑存储到可导出的常量中。我希望能够在我的所有httpClient服务中注入这个逻辑,所以我选择将它添加到providers列表中。

下面是我如何调用retryWhen逻辑的一个例子:

代码语言:javascript
运行
复制
  constructor(private http: HttpClient,
    private injector: Injector,
    @Inject('tokenExpired') private tokenExpired: any,
    ) {}

  getSomeData():Observable<any>{
      return this.http.get<any>(this.apiUrl + "/user/get/someData").pipe(retryWhen(this.tokenExpired(1, this.injector.get(LoginService)}))); 

这不管用。尽管使用注入器获取实例,但tokenExpired逻辑中的tokenExpired变量仍然为空。有人能告诉我怎样才能让这件事起作用吗?我需要一个单例loginService实例,如果不可能,我可以在HttpClient函数中使用这个单例HttpClient对象直接调用刷新令牌api端点。它之所以需要是一个单例,是因为我不希望对不同的数据调用多个api调用相同的刷新令牌api,因为每个api都因为令牌过期而无法获得数据。我只想要一个刷新令牌调用,然后将结果分发给所有订阅者。我用的是share()操作符。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-12 07:31:03

您可以在concatMap中使用以下内容:

代码语言:javascript
运行
复制
loginService.requestNewToken().subscribe(success => {
  console.log(`Attempt ${retryAttempt}: retrying in ${1000}ms`);
  return timer(50);
}, 

这是行不通的,因为您必须返回一个可观察到的concatMap。所以也许你可以这样做:

代码语言:javascript
运行
复制
return loginService.requestNewToken()
  .pipe(
    concatMap(success => {
      console.log(`Attempt ${retryAttempt}: retrying in ${1000}ms`);
      return timer(50);
    }),
  );

很难判断其他人是不是出了什么问题。我得做一个可复制的演示。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62335967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档