angular - 多个 Observables 共享单个 Error rxjs angular
问题描述
我正在尝试使用 Oauth2 身份验证处理 API 请求。
我有一个authService
具有三个属性(accessToken
, refreshToken
& refreshTokenObservable
– 稍后描述)和apiGet()
使用 Authorization 标头创建 HTTP GET 请求的方法,如下所示:
apiGet(cleanedPath:string) {
return this.config.getConfig().pipe(mergeMap((config: Config) => {
[...] // Cleans parameters and creates a final query string
// Adding access token as header
let headers: object = {headers: new HttpHeaders().set('Authorization', this.accessToken)}
return this.http.get<any>(cleanedPath, headers).pipe(catchError(this.handleApiGetError.bind(this, cleanedPath)));
}));
}
我希望该handleApiGetError()
方法调用新的刷新令牌并尝试重复apiGet()
,我尝试将多个apiGet()
调用连接到单个可观察对象,如下所示:
private handleApiGetError(cleanedPath:string, error: HttpErrorResponse) {
if (!this.refreshTokenObservable) {
// getAccessByRefreshToken() is simple HTTP post
this.refreshTokenObservable = this.getAccessByRefreshToken();
}
return this.refreshTokenObservable.pipe(mergeMap(()=> {
return this.apiGet(cleanedPath);
}));
}
然而,这并没有奏效,因为它在每次失败时都需要新的令牌apiGet()
,导致 OAuth 服务返回多个 E401(令牌已经被撤销)。
有没有办法将apiGet()
观察者绑定在一起,并且在错误的情况下只调用一次刷新令牌请求并重新调用失败的apiGet()
调用?
解决方案
考虑使用retryWhen
to 仅重试一次,最重要的是反转控件,以便您ErrorHandler
不负责再次重试(通过调用其调用者)。只有在完成返回的 Observable 后,才会重试
使用您的 HTTP 请求,如下所示:retryWhen
this.handleApiGetError()
apiGet(cleanedPath: string) {
return this.config.getConfig().pipe(
mergeMap((config: Config) => {
return this.http.get<any>(cleanedPath, headers).pipe(
retryWhen(x => this.handleApiGetError())
);
})
);
}
private handleApiGetError(error: HttpErrorResponse) {
return this.refreshTokenObservable;
}
话虽如此,handleApiGetError
可能没有必要,因为您可以getAccessByRefreshToken
直接调用,如下所示:
apiGet(cleanedPath: string) {
return this.config.getConfig().pipe(
mergeMap((config: Config) => {
return this.http.get<any>(cleanedPath, headers).pipe(
retryWhen(this.getAccessByRefreshToken)
);
})
);
}
推荐阅读
- c++ - 识别内存损坏
- reactjs - 无法在 reactjs 的 return 语句中使用过滤器功能。投掷错误
- matlab - 如何比较 lsqnonlin() 正在解决的算法
- automation - 创建一个自动化语法,生成一种序列不重复数字的语言
- go - Golang:RabbitMQ 接收器 + 并发地图 + http 服务器
- redux - Redux Toolkit 说这个片段(19 行)是更短的代码(与原始 12 行相比)混淆
- javascript - JavaScript 使用 setInterval 获取“不安全评估”
- python - 在 json.dumps 之后在 python 中添加额外的 \\ 的 Rest API 请求
- html - 如何在 CSS 中使图像适合此 PNG 图像的形状?
- parsing - 使用 Pest.rs,如果 PUSH 是可选的,如何避免“在空堆栈上调用 peek”?