首页 > 解决方案 > 轮询服务,直到我得到响应或在特定时间段后超时

问题描述

要求 调用服务。

如果该服务返回数据,请将数据设置为变量。功能结束

如果该服务返回 data = null,则每 20 秒重复调用一次该服务,直到它返回 data=“列表或对象”或调用该服务 2 分钟并停止。

我尝试 的内容需要每 20 秒轮询一次此服务 getUrlById(id),直到我在 this.url 中获得响应或 6 分钟后超时。

尝试了以下未按预期工作的解决方案。

pollUrl(id) {
    interval(2000).pipe(
      timeout(600000),
      takeWhile(() => this.url)
    ).subscribe(i => {
      this.service.getUrlById(id).subscribe(res =>{
        if(res && res["result"]){
          this.url = res["result"];
        }
      })
      })
  }

来自评论 我试过的

在这里调用了虚拟服务demo

此处虚拟服务返回 data = null。所以根据要求,我需要每 20 秒调用一次服务,直到 2 分钟。那是行不通的。

没有必要使用这个代码,我想达到要求。可以有不同的做法。

标签: angulartypescriptrxjsangular8

解决方案


只需使用find 运算符(查找通过某些测试并发出该Docs的第一个值),因此返回的 Observable 在定义getUrlById后立即完成response.result,如下所示:

interval(2000)
  .pipe(
    exhaustMap(() => this.service.getUrlById(id)), // <== switch subscription to `getUrlById` 
    find(x => x && x.result && x.result.length > 0),
    timeout(6 * 60 * 1000)
  )
  .subscribe(i => { })

这是一个现场演示

可选地使用扩展,以便只要当前尚未完成,就不会发送进一步的请求。

const api$ = this.service.getUrlById(id);

api$.pipe(
    expand(x => x && x.result && x.result.length > 0 ? EMPTY : api$.pipe(delay(2000))),
    last(), // get the result
    timeout(6 * 60 * 1000)
)
.subscribe(i => { })

推荐阅读