angular - Angular/RxJS 轮询超时和间隔取决于 api 响应时间
问题描述
我正在尝试编写一个方法来轮询 API 操作的状态,返回一个可观察的,它将发出每个状态调用的结果(因为它包含我想要显示的进度信息),直到它获得完成状态,发出那个状态,然后就完成了。
我到目前为止是这样的:
pollStatus(identifier: string): Observable<OperationStatusResource> {
const obs = interval(1000)
.pipe(
startWith(0),
switchMap( () => this.apiService.operationStatus(identifier) ),
takeWhile( (value, index) => {
return value.status != OPERATION_STATUS.COMPLETE;
}, true)
)
return obs;
}
哪个有效,我理解,但我认为我可以做得更好,我正在努力弄清楚如何做。这每秒请求一个新状态,如果尚未完成,则取消前一个状态。我确实想在每次发送新请求时取消以前的请求,以确保我永远不会因互联网恶作剧而出现故障,但是:
- 我希望在最后一个请求的响应之后开始应用延迟。所以像 req->resp->1000ms->req 等。
- 我想超时每个请求。因此,例如,如果一个请求在 5 秒后没有返回响应,我将取消它并重试
如果响应需要一段时间,我也很乐意以任何其他方式来实现相同的耐心,但不愿意永远等待,如果响应很快回来,也不会请求太快。
如果我可以添加整体失败条件或超时,例如放弃,如果您连续 3 次超时,或者整个事情需要超过 5 分钟,或者如果我连续收到 3 个非 200 代码,则可以加分。
解决方案
在上面睡觉之后,我认为这个答案最后加上重试是我应该使用的。
pollStatus(identifier: string): Observable<OperationStatusResource> {
const obs = defer(() => this.apiService.operationStatus(identifier))
.pipe (
timeout(10000),
repeatWhen(notification => notification.pipe(delay(1000))),
takeWhile( (value, index) => {
return value.status != OPERATION_STATUS.COMPLETE;
}, true)
).pipe(retry(1))
return obs;
}
它将发出初始请求,然后等待最大毫秒数(超时)的响应,并在获得响应后等待数毫秒(延迟)。
最后的重试是我需要的。如果超时,请求将被取消,重试将重试(一次,在本例中)
推荐阅读
- gitlab - 自托管 Gitlab 运行程序注册失败的 x509 证书,由 GKE 上的未知权威通过 helm install 签名
- c# - 如何处理字符串中的取消字符?
- angular - 如何在 Angular 中使用 mat-calendar 实现日期范围选择器
- python - Python 请求连接到被阻止的服务器
- php - 如何修复此 php 文件以发送电子邮件
- java - 如何在 Kotlin 上启用 GPS 定位?
- swift - 如何在 Swift 中处理多种可能的场景
- python - 嘿伙计们,我是 python 新手,需要有关此功能的一些建议
- bigcommerce - Bigcommerce 如何在带有财富主题的标题上设置登录和注册链接
- c - const char 编译器优化