可观察的重试/重试当使用flatmap时 [英] Observable retry / retryWhen with flatmap
问题描述
我有以下代码来获取id,然后获取与id相关的数据。
I have the following code to get id and then data related to the id.
process(): Observable<any> {
let id: number;
return this.getId().flatMap(
(response: number) => {
id = response;
return this.getData(id)
}
).flatMap(
(data: any) => {
return Observable.of(data);
}
);
}
getData(id: number): Observable<any> {
// retry if response.status is not complete
return this.service.getData(id).map(response => return response.data);
}
我想在getData方法上添加重试逻辑,直到response.status不是完成。我尝试在this.getData(id)之后添加重试/重试但没有运气。有什么建议吗?
I would like to add retry logic on getData method until response.status is not complete. I tried adding retry/retryWhen after this.getData(id) but no luck. Any suggestions please?
推荐答案
重试
和 retryWhen
适用于错误处理,这意味着源observable必须为这些运算符产生错误才能生效。我想在你的情况下,你想重试不是出错,而是你不喜欢的状态。
retry
and retryWhen
are suitable for error handling, meaning that the source observable has to produce an error for these operators to make an effect. I guess that in your case you want to retry not on error, but on a status that you don't like.
可能最简单的方法就是在某个时间间隔内拨打服务电话并按照您想要的状态进行第一次回复:
Probably the simplest way to achieve that would be to make service calls on some interval and take the first response with the status you want:
getData(id) {
return Observable.interval(100)
// make 5 attempts to get the data
.take(5)
.concatMap(() => this.service.getData(id))
.filter(response => response.status === "complete")
.take(1)
.map(response => response.data)
}
现在 getData()
返回一个observable要么发出一个对应于具有完整状态的响应的单个值,然后在完成5次尝试获取具有所需状态的数据失败后完成,或完成,而不会发出任何值(响应评论时更新了答案) )。
Now getData()
returns an observable that either emits a single value that corresponds to a response with a "complete" status and then completes, or completes without emitting any value after 5 unsuccessful attempts to get the data with the desired status (the answer updated in response to a comment).
U pdate:
当然,可以将错误状态的响应转换为错误并使用重试
功能,正如您所建议的那样:
It is, of course, possible to turn responses with "bad" statuses into errors and use the retry
functionality, as you proposed:
getData(id) {
return this.service.getData(id)
.concatMap(response => response.status === "complete" ?
Observable.of(response) :
Observable.throw("Bad status"))
.map(response => response.data)
.retry(5);
}
如果出现问题,此代码将尝试获取最多6个数据时间(1个初始值+ 5个重试次数)然后将产生一个您必须处理的错误,例如使用 catch
运算符。一个缺点是这种方式不能将真实错误(例如网络故障)与错误状态产生的错误区分开来,但这可以通过 retryWhen
来处理。
If things go wrong, this code will try to fetch the data at most 6 times (1 initial + 5 retries) and then will produce an error that you would have to handle, for example with catch
operator. One drawback is that this way does not distinguish "real" errors (e.g. network failures) from errors produced out of bad statuses, but this could be handled with retryWhen
.
这篇关于可观察的重试/重试当使用flatmap时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!