Angular/RxJS 轮询,超时和间隔取决于 api 响应时间

标签 angular rxjs polling

我正在尝试编写一个方法来轮询 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 代码,则可以获得奖励积分。

最佳答案

睡过之后,我认为THIS我应该使用在最后添加重试的答案。

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;
}

它将发出初始请求,然后在最大毫秒数(超时)内等待响应,并在收到响应后等待一定毫秒数(延迟)。

最后的重试正是我所需要的。如果超时,请求将被取消,重试将再次尝试(在本例中为一次)

关于Angular/RxJS 轮询,超时和间隔取决于 api 响应时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58566215/

相关文章:

mysql - 实现现场投票系统

javascript - Angular 2 中的一个组件如何通过调用另一个组件的方法来弹出另一个组件?

Angular 2 - 带有 formControlName 的 ng-bootstrap 下拉菜单

angular - 使用 RxJS forkJoin 时传递参数的最佳方法

javascript - Vue 中的 RxJS 入门

angular - 如何使用 RXJS Observables 轮询服务?

c - 非阻塞获取字符

angular - 在组件元素上使用指令

javascript - Angular 2+等待订阅完成更新/访问变量

javascript - 使用 RxJS 进行 D3 选择事件