我已经看过十几种实施重试策略的方法,我觉得我真的非常接近。在takeWhile()
完成后,我所拥有的内容并不会引发错误。
getItems(): Observable<ListItem[]> {
return this.authHttp.get(URL + '/items')
.retryWhen(e =>
e.scan((errorCount, err) => errorCount + 1, 0)
.takeWhile(errorCount => errorCount < 4)
.delay(3000))
.map(this.dataService.extractData)
.catch(err => this.dataService.handleError(err, 'The items could not be retrieved.'))
}
我已经看到了一些看似锯齿状的代码片段,可能会让它完成。我尝试在.finally()
之前插入.delay()
。
一旦我解决了这个问题,我就想将errorCount传递回我的订阅,以便我可以显示有用的内容。 &#34;重试1/4。&#34;让用户知道发生了什么的东西。
答案 0 :(得分:3)
使用retryWhen
,您可以使用传递给通知程序的observable做一些事情。你可以:
在使用takeWhile
时,您正在发送通知然后正在完成 - 它会看到重试停止而没有错误。
听起来您想要发出通知,但随后会抛出错误:
getItems(): Observable<ListItem[]> {
return this.authHttp.get(URL + '/items')
.retryWhen(e => e.scan((errorCount, error) => {
if (errorCount >= 4) {
throw error;
}
return errorCount + 1;
}, 0)
.delay(3000)
)
.map(this.dataService.extractData)
.catch(err => this.dataService.handleError(err, 'The items could not be retrieved.'));
}
要将重试逻辑划分为可重复使用的函数,您可以使用let
- “让我拥有整个可观察的” - 运算符:
import 'rxjs/add/operator/let';
function handleRetry<T>(source: Observable<T>): Observable<T> {
return source.retryWhen(e => e.scan((errorCount, error) => {
if (errorCount >= 4) {
throw error;
}
return errorCount + 1;
}, 0)
.delay(3000)
);
}
getItems(): Observable<ListItem[]> {
return this.authHttp.get(URL + '/items')
.let(handleRetry)
.map(this.dataService.extractData)
.catch(err => this.dataService.handleError(err, 'The items could not be retrieved.'));
}