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

Throw error after the retry fails with Angular http.get

我正在尝试通过重试实现 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 次,那么它将 returns 成功(与空数据)。我不想要那个。相反,我希望它抛出最后一个错误。

我试着把 .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);
    });
});

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

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

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

不幸的是,这意味着您必须在 retryWhen 中自己跟踪重试计数 - 因此对于 5 次计数,您只需让它 return 错误(这将触发重试),最后计数 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 已完成(即。 returned 完成,所以没有错误)。这就是 concat 不能抛出最后一个错误的原因,因为它从未收到过它。