【问题标题】:Throw error after the retry fails with Angular http.getAngular http.get 重试失败后抛出错误
【发布时间】:2018-02-27 16:20:41
【问题描述】:

我正在尝试通过重试来实现 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);
    });

如果收到错误 500,它将继续重试最多 5 次。但是,如果它连续 5 次失败,则它返回成功(数据为空)。我不想要那个。相反,我希望它抛出最后一个错误。

我尝试将.concat(Observable.throw({})) 放在 take() 之后,这很有效,但它没有提供任何信息,例如最近错误的状态代码。

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

【问题讨论】:

    标签: angular reactjs rxjs retrywhen


    【解决方案1】:

    您无需使用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);
        });
    });
    

    【讨论】:

      【解决方案2】:

      .retryWhen 只能完成或错误 - 在这两种情况下,都会中止进一步的重试。 See docs.

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

      所以使用.take() 不会解决您的问题。

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

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

      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);
        });
      

      附带说明,添加 .concat(Observable.throw({})) 并不能解决您的问题,因为当它触发时,您的 5 次重试已完成,因此 retryWhen 已完成(即返回完成,所以没有错误)。这就是 concat 无法抛出最后一个错误的原因,因为它从未收到它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-06
        • 1970-01-01
        • 2017-02-15
        • 1970-01-01
        • 2019-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多