Angular 在RxJs中执行操作后,如何重试可观察到的?
我使用Angular 2和RxJS从API层检索数据。我编写了一个基本服务来处理HTTP请求。以下代码在我的服务中执行此操作:Angular 在RxJs中执行操作后,如何重试可观察到的?,angular,rxjs,reactive-programming,Angular,Rxjs,Reactive Programming,我使用Angular 2和RxJS从API层检索数据。我编写了一个基本服务来处理HTTP请求。以下代码在我的服务中执行此操作: protected apiGet(uri: string): Observable<HttpMappedResponse<T>> { return this.mapAndHandle<T>(this.http.get(uri)); } private mapAndHandle<T>(observable: Obs
protected apiGet(uri: string): Observable<HttpMappedResponse<T>> {
return this.mapAndHandle<T>(this.http.get(uri));
}
private mapAndHandle<T>(observable: Observable<Response>): Observable<HttpMappedResponse<T>> {
const o = observable
.map(res => {
const data = res.json() || {};
const mappedResponse = new HttpMappedResponse<T>(res, data);
// Retrieve page information from HTTP headers
mappedResponse.pageInfo = new PageInfo(res.headers);
return mappedResponse;
})
.share();
o.subscribe(null, e => this.errorService.handleHttpResponse(e));
return o;
}
但这并没有给我正确的结果
有接线员可以帮我吗?retryWhen()似乎是最符合逻辑的,但我总是把自己和RxJs搞得一团糟 您遇到的问题之一是您没有将电话链接起来。您的刷新调用应该链接到您的重试调用,它们应该利用
flatMap
或类似的工具将其保持在相同的可观察流中
看看这个问题 以下是您实现此目标的方法: 您需要从RxJS添加
catch
操作符。这就是错误所在,您可以相应地处理它
为了让刷新逻辑通过拦截器,您需要返回调用,函数还应该返回一个可观察的
。例如,修改上述原始逻辑:
this.http.request(url, options)
.map((res: Response) => res.json())
.catch((error: any) => {
const err = error.json();
// Refresh JWT
if (err.status === 401) {
// refreshToken makes another HTTP call and returns an Observable.
return this.refreshToken(...);
}
return Observable.throw(err);
});
如果您希望能够重试原始请求,您可以做的是传递原始请求数据,以便在成功刷新令牌后可以再次进行调用。例如,这就是refreshtToken
函数的外观:
refreshToken(url: string, options: RequestOptionsArgs, body: any, tokenData: any): Observable<any>
return this.post(`${this.url}/token/refresh`, tokenData)
.flatMap((res: any) => {
// May want to use response data to set new tokens in your local storage or whatever here...
// This is where I retry the original request
return this.request(url, options, body);
});
}
refreshttoken(url:string,options:RequestOptionsArgs,body:any,tokenData:any):可观察
返回this.post(`${this.url}/token/refresh`,tokenData)
.flatMap((res:any)=>{
//可能需要使用响应数据在本地存储或其他任何地方设置新令牌。。。
//这是我重试原始请求的地方
返回此.request(url、选项、正文);
});
}
让我知道我的答案是否能引导您走向正确的方向。这都是伪代码,但它应该让您大致了解您可以做什么(您已经知道需要采取的步骤)。在重试您的请求时,只需利用flatMap
,您就可以将其保存在相同的可观察流中。谢谢!我看到过flatMap()的示例,但无法真正理解它以前在做什么。我还花了几个小时追踪了一个愚蠢的重构错误,我把它引入了我的代码中,它替换了我文章中的主体,并将命令放在了标题中。这当然没有帮助我理解这里!很高兴我能帮上忙:)我也被困在这个问题上了一段时间,但最终发现我可以利用flatMap
来解决它。你可能可以让它更简洁,但你现在明白了。我的完整实现相当复杂——尝试使事情尽可能通用的本质:)this.request(url、选项、正文);这给了我最后一条线索,我有一个用于Get/Post/Put的常见错误处理程序。
refreshToken(url: string, options: RequestOptionsArgs, body: any, tokenData: any): Observable<any>
return this.post(`${this.url}/token/refresh`, tokenData)
.flatMap((res: any) => {
// May want to use response data to set new tokens in your local storage or whatever here...
// This is where I retry the original request
return this.request(url, options, body);
});
}