Angular 使用http.get重试失败后抛出错误

Angular 使用http.get重试失败后抛出错误,angular,reactjs,rxjs,retrywhen,Angular,Reactjs,Rxjs,Retrywhen,我正在尝试通过重试实现Angular5 http.get。我写 http.get<any>('/api/study').retryWhen( (errors: Observable<any>):Observable<any> => { return errors.flatMap((error: any) => { if (error.status == 500) {

我正在尝试通过重试实现Angular5 http.get。我写

http.get<any>('/api/study').retryWhen(
    (errors: Observable<any>):Observable<any> => {
        return errors.flatMap((error: any) => {
            if (error.status  == 500) {
                return Observable.of(error.status).delay(1000);
            }
            return Observable.throw(error);
        }).take(5);
    });
http.get('/api/study').retryWhen(
(错误:可观察):可观察=>{
返回错误。flatMap((错误:any)=>{
如果(error.status==500){
返回可观测的(错误状态)延迟(1000);
}
返回可观察抛出(错误);
}).采取(5);
});
如果出现错误500,将继续重试最多5次。但是,如果一行中有5次失败,那么它返回success(数据为空)。我不想那样。相反,我希望它抛出最后一个错误

我试图将
.concat(Observable.throw({}))
放在take()之后,这是可行的,但它没有给我任何信息,比如最近错误的状态代码


上次重试失败后,如何获取最近的错误?

您不需要使用
take(5)
来计算失败的尝试次数,也不需要使用局部变量自己计算

例如,您可以这样做:

http.get<any>('/api/study').retryWhen((errors: Observable<any>) => {
    let errors = 0;

    return errors.flatMap((error: any) => {
        if (errors++ < 5 && error.status  == 500) {
            return Observable.of(error.status).delay(1000);
        }
        return Observable.throw(error);
    });
});
http.get('/api/study').retryWhen((错误:可观察)=>{
设误差=0;
返回错误。flatMap((错误:any)=>{
if(errors++<5&&error.status==500){
返回可观测的(错误状态)延迟(1000);
}
返回可观察抛出(错误);
});
});

.retry当
只能完成或出错时-在这两种情况下,将中止进一步的重试

因此,当您添加
.take(5)
时,您基本上是告诉它重试5次,然后完成,此时它只能完成(因此也不能返回错误-它是一个或另一个,而不是两个)

因此,使用
.take()
无法解决您的问题

不幸的是,这意味着您必须在retryWhen中自己跟踪重试次数-因此对于5次计数,您只需让它返回错误(这将触发重试),最后在计数6时手动抛出错误。然后可以在catch块中捕获最后的错误

类似这样的内容(代码未经测试,但显示了想法):

http.get('/api/study').retryWhen(err=>{
console.log(“重试”);
设重试次数=0;
返回错误
.延迟(1000)
.map(错误=>{
如果(重试次数+==6次){
日志('重试次数',重试次数);
投掷误差{
console.log('catch');
可观察的回报率(误差);
})
.订阅(数据=>{
console.log('subscriber');
控制台日志(数据);
});
作为补充说明,添加.concat(Observable.throw({}))并不能解决您的问题,因为当它触发时,您的5次重试已经完成,因此retryWhen已经完成(即返回complete,所以没有错误)。这就是为什么concat不能抛出最后一个错误,因为它从未收到它

http.get<any>('/api/study').retryWhen(err => {
    console.log('retrying');
    let retries = 0;
    return err
      .delay(1000)
      .map(error => {
        if (retries++ === 6) {
          console.log('retry number ', retries);
          throw error; <- THIS WILL CAUSE retryWhen to complete
        }
        return error; 
      });
  })
  .catch(err => {
    console.log('caught');
    return Observable.of(err);
  })
  .subscribe(data => {
    console.log('subscriber');
    console.log(data);
  });