我有以下代码来获取id,然后获取与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)之后添加重试/重试但没有运气。有什么建议吗?
答案 0 :(得分:4)
retry
和retryWhen
适用于错误处理,这意味着源observable必须为这些运算符产生错误才能生效。我想在你的情况下,你想重试不是出错,而是在你不喜欢的状态。
实现这一目标的最简单方法可能是在某个时间间隔内进行服务调用,并采用您想要的状态进行第一次响应:
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,该observable发出一个对应于具有“完成”状态的响应的值,然后完成,或完成,但在5次尝试获取数据失败后没有发出任何值具有所需状态(答案更新后的答案)。
<强>更新强>
当然,可以将“错误”状态的响应转换为错误,并使用retry
功能,如您所建议的那样:
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
来处理。
答案 1 :(得分:0)
我尝试过重试方法,但它确实有效。
(Observable ...).retry(2).map(...).subscribe(...)
当我进行http呼叫并且响应是例如404时,它重试该呼叫两次。