【问题标题】:Angular/RxJS Polling with timeout and interval dependent on api response timeAngular/RxJS 轮询超时和间隔取决于 api 响应时间
【发布时间】:2020-02-22 06:15:04
【问题描述】:

我正在尝试编写一个方法来轮询 API 操作的状态,返回一个 observable,它将发出每个状态调用的结果(因为它包含我想要显示的进度信息),直到它得到一个完成状态,发出该状态,然后完成。

到目前为止,我所拥有的是:

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 代码,则可以加分。

【问题讨论】:

  • “我确实想取消以​​前的请求”和“我想在第一个请求响应后才进行下一个请求”并没有真正在一起。如果您等待响应,则不会有先前的取消请求。
  • @IngoBürk 我想等待 X 秒,如果在那段时间内没有响应,那么我才想取消它并发送一个新的。我担心的是,如果我每 500 毫秒轮询一次并且服务器需要 600 毫秒来响应,那么我将永远得不到响应。

标签: angular rxjs polling


【解决方案1】:

睡在上面之后,我认为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;
}

它将发出初始请求,然后等待响应的最大毫秒数(超时),并在获得响应后等待数毫秒(延迟)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多