我有一个角度的网页应用程序,使用访问令牌,可以过期。当它们过期时,401状态响应被发送回应用程序,然后由retryWhen
操作符处理。进行令牌刷新api调用的逻辑已放置在我在providers
数组@NgModule(
中声明的可注入函数中。
该函数如下所示:
{ 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逻辑的一个例子:
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()
操作符。
谢谢
发布于 2020-06-12 07:31:03
您可以在concatMap
中使用以下内容:
loginService.requestNewToken().subscribe(success => {
console.log(`Attempt ${retryAttempt}: retrying in ${1000}ms`);
return timer(50);
},
这是行不通的,因为您必须返回一个可观察到的concatMap
。所以也许你可以这样做:
return loginService.requestNewToken()
.pipe(
concatMap(success => {
console.log(`Attempt ${retryAttempt}: retrying in ${1000}ms`);
return timer(50);
}),
);
很难判断其他人是不是出了什么问题。我得做一个可复制的演示。
https://stackoverflow.com/questions/62335967
复制相似问题