我是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中进行这种错误处理的惯用方式是什么?
答案 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
则可以延迟重试。