我一直在try 实现我自己的RxJS操作符,这样我就可以将它"插入"到我的Angular 的HttpClient.我希望保持请求每X毫秒进行一次(轮询),但也希望在出现错误的情况下使用某种增量策略重试请求.以下是一个细目:
- 每X毫秒重复一次请求(轮询)
- 如果出现错误,应每隔Y毫秒重试一次请求,但如果请求再次失败,则毫秒数应加倍(例如,第一次失败1000ms,第二次失败2000ms,第三次失败4000ms),直到达到限制,如果达到该限制,例如1分钟,则重试不会再次增加,所有后续重试都应等待1分钟.
- 成功重试后,重试毫秒计数器应重新启动,以便下一次它将从Y毫秒开始重试.
- 当执行一个请求时,无论出于何种原因,都需要花费大量时间来响应,我们需要确保不会触发或取消任何其他请求(我可以在这里看到linatMap的可能用法!)
以下是我目前掌握的情况:
function repeatWithBackoff<T>(delay: number, maxDelay = 60000) {
return (source: Observable<T>) =>
timer(0, delay).pipe(
concatMap(() => {
return source.pipe(
retryWhen((attempts) => {
return attempts.pipe(
concatMap((attempt, i) => {
const backoffDelay = Math.min(delay * Math.pow(2, i), maxDelay);
return timer(backoffDelay);
})
);
})
);
})
);
}
以下是我使用它的方法:
httpClient.post(...)
.pipe(repeatWithBackoff(1000, 60000))
.subscribe((x) => console.log('Result', x));
显然,我的代码是kinda works,但重试不能正常工作,我预计请求失败时不会发生任何事情(例如,no console.log()),但我可以看到可观察到的数据打印到控制台. 此外,如果有人有一个巧妙的主意来简化该功能,我将不胜感激:)