【问题标题】:RXJS retry based on another subscriptions resultRXJS 基于另一个订阅结果重试
【发布时间】:2020-12-14 16:48:20
【问题描述】:

我正在调用需要在服务器上进行身份验证的端点。

/users/:userId/my/endpoint => getData(): Observable<any>

如果身份验证过期,服务器将返回错误消息。然后我可以使用我通过 POST 发送的客户端密码刷新此身份验证

/refresh/me => refreshAuth(): Observable<any>

之后,我将再次发送第一个请求并获得成功的响应(快乐的情况)。

我怎样才能用一个 Observable 实现这一点?我知道,例如catchErrorretry

getData()
  .pipe(
    catchError(e => {
      if (error.code === 1224) {
        return refreshAuth();
      }

      return throwError(error);
    }),
    retry(1)
  ).subscribe();

但这会重试每个错误情况,对吗?如何在特定的身份验证过期案例上重试整个链?

【问题讨论】:

  • 查看retryWhen 这样您就可以检查错误,并且仅在满足您的条件时才发出重试

标签: rxjs


【解决方案1】:

这就是它的实现方式:

getData()
  .pipe(
    retryWhen(error => error.pipe(
      exhaustMap(e => (e.code == 1224) ? refreshAuth() : throwError(e))),
      take(1)
    )
  )
  .subscribe();

【讨论】:

  • 这已经很有帮助了,谢谢。但是如果refreshAuth() 失败,现在会在无限循环中调用getData()。我如何确保整个链条只重复一次?
  • exhaustMap() 获胜,谢谢!在stackoverflow.com/questions/44911251/… 的帮助下,我也能够通过concatMapiif 解决这个问题,但是您的解决方案要干净得多!
  • 留下了一件奇怪的事情......getData() get 后面的 API 调用在重试时被取消。也许我的实现有问题,我会更深入地检查一下。
  • 你的意思是第一次重试后?这是预期的行为
  • 是的,在第一次重试时。 getData() => refreshAuth() => getData()。第二个 getData() 被取消了。所以我需要使用 take(2)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多