如果出现错误,我想在第二次延迟时重试get
几次请求,但如果所有尝试失败,则执行错误处理程序。
以下代码重试请求,但catch永远不会执行。我该如何解决?
import {Response, Http} from '@angular/http';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
this.http.get("/api/getData").map(data => {
console.log('get')
return data.json()
})
.retryWhen(err => {
console.log('retry')
return err.delay(1000).take(5)
})
.catch(err => {
console.log('catch')
this.handleHttpError(err)
return err
})
.subscribe(data => {
console.log('subscribe')
console.log(data)
})
答案 0 :(得分:6)
这里的问题是,当Bar
中的回调回复通知Observable发送retryWhen
通知时,它会进一步传播为complete
,这不是您想要的你的描述。
您希望将其作为complete
通知发送,这意味着您无法使用error
并使用其他运算符来重新抛出错误。
例如:
take()
您可以自己计算Observable.defer(() => Observable.throw("It's broken"))
.retryWhen(err => {
console.log('retry');
let retries = 0;
return err
.delay(1000)
.map(error => {
if (retries++ === 5) {
throw error;
}
return error;
});
})
.catch(err => {
console.log('catch');
return Observable.of(err);
})
.subscribe(data => {
console.log('subscribe');
console.log(data);
});
变量中的重试次数,如果达到某个限制,只需重新抛出错误。 retries
运算符用try-catch块包装所有回调,因此在其callable中抛出的任何错误都将作为map()
信号发送。
答案 1 :(得分:2)
return err.delay(1000).take(5)
重试后应该出错,例如:
return err.delay(1000).take(5).concat(Observable.throw(err))
感谢@martin指出此代码实际上抛出了Observable而不是错误。
答案 2 :(得分:0)
将现代rxjs与pipe
配合使用,将在retryWhen
运算符中返回的可观察对象通过某种逻辑传递给逻辑,如果满足特定条件,该逻辑将引发错误。
https://stackblitz.com/edit/rxjs-retrywhen-to-catch
import { interval, of, throwError, timer } from 'rxjs';
import { catchError, mergeMap, switchMap, retryWhen, tap } from 'rxjs/operators';
const source = interval(1000);
const example = source.pipe(
// simulate error
switchMap(count => count > 3
// this will be caught by retryWhen
? throwError('Error from source!')
: of(count)
),
retryWhen(err$ => err$.pipe(
// display error from source
tap(console.error),
// i === index, AKA how many tries
mergeMap((err, i) => i > 1
// throw error, which is caught by catchError
// or second argument to subscribe function if catchError not used
? throwError('Error from retry!')
// wait specified duration before retrying
: timer(3000)
)
)),
catchError(err => of('There was an error, but we handled it. '))
);
example.subscribe(
console.log,
() => console.error('Nothing reaches this error handler because we used catchError')
);
/*
RESULT
0
1
2
3
Error from source!
0
1
2
3
Error from source!
0
1
2
3
Error from source!
There was an error, but we handled it.
*/
的启发