RxJS中的自我修复错误处理

时间:2018-08-21 15:05:25

标签: javascript node.js rxjs observable rxjs6

我是RxJS的新手。

我有一个承诺的基本HTTP客户端。它具有 login()方法,该方法从服务器获取令牌并将其存储在内部,以供其他方法使用。

当令牌过期时,服务器将响应 401 HTTP错误,在这种情况下,我想再次调用 login()并重试该请求。另外,重试其他类型的错误。

我不确定如何在RxJS中对其建模,我有一些工作,但是我希望有更好的方法来实现。

这是装饰器中的装饰器,该装饰器应用于所有需要身份验证的方法,此处为 wrappedFunc

        return interval(100)
            .pipe(
                startWith(0),
                switchMap(() => {
                    return wrappedFunc.apply(this, args)
                }),
                retryWhen(errors$ => errors$.pipe(
                    switchMap((error) => {
                        if (error.response.status === 401) {
                            return this.login()
                        } else {
                            return of(error)
                        }
                    }),
                    scan((attempts, currentError) => {
                        if (attempts > 5) {
                            throw currentError
                        }
                        return attempts + 1
                    }, 0),
                )),
                first()
            )

在RxJS中进行这种错误处理的惯用方式是什么?

1 个答案:

答案 0 :(得分:2)

interval(100)每100毫秒发出一次,而switchMap将取消正在进行的订阅并重新订阅,因此,如果wrappedFunc调用花费的时间超过100毫秒,它将永远不会“发生”-它将尝试使一次又一次地打电话。

我认为您需要以下方面的更多信息:

return defer(() => wrappedFunc.apply(this, args))
  .pipe(
    retryWhen(errors$ => errors$.pipe(
      switchMap((error) => {
        if (error.response.status === 401) {
          return this.login()
        } else {
          return of(error)
        }
      }),
      scan((attempts, currentError) => {
        if (attempts > 5) {
          throw currentError
        }
        return attempts + 1
      }, 0),
      delay(100),
    ))
  );

此处的defer用作包装器,因此wrappedFunc可以返回Promise或Observable,而delay则可以延迟重试。