使用RxJS进行轮询可以恢复丢失的事件

时间:2019-06-09 15:33:24

标签: javascript rxjs

我正在尝试使用RxJS轮询事件。但是,我只能访问一个功能,即getEvent()。我可以使用getEvent函数做两件事:

  1. getEvent("latest")-这将为我提供最新的事件对象
  2. getEvent(eventId)-我传入一个整数,它将为我提供与eventId相对应的事件对象。

事件ID总是从0开始递增,但是问题是,如果我的轮询间隔不够小,我可能会错过事件。

例如,如果我执行一个getEvent("latest")并且得到了ID为1的事件,那就太好了。但是,如果下次下次调用它时,我得到的ID为3,则表示我错过了一个事件。

在这种情况下,我想使用可观察的高阶函数来调用getEvent(2)getEvent(3),这样我正在创建的流的使用者就不必担心丢失事件。

现在,我所拥有的就是这样:

timer(0, 500).pipe(
  concatMap(() => from(getEvent("latest"))
)

在某些情况下,我正在撰写以下博客文章:https://itnext.io/polling-using-rxjs-b56cd3531815

1 个答案:

答案 0 :(得分:2)

使用expand递归调用GET非常适合这里。这是an example with DEMO

const source = timer(0, 2000)

const _stream = new Subject();
const stream = _stream.asObservable();

const s1 = source.pipe(tap(random)).subscribe()    

const sub = stream.pipe(
  startWith(0),
  pairwise(),  
  concatMap((v: Array<number>) => {
    let missing = v[1] - v[0];
    return missing ? getMissing(v[0], missing) : EMPTY
  })
).subscribe(console.log)

function getMissing(start, count) {
  return getById(start).pipe(
    expand(id => getById(id+1)),
    take(count)
  )  
}

// helper functions for DEMO

let i = 1;
function random() {. // THIS IS YOUR getEvent('latest')
  if (i < 10) {
    i+=2;
    _stream.next(i
      // (Math.floor(Math.random() * 8))
    )
  }
}

function getById(id) {.  // THIS IS YOUR getEvent(eventId)
  return of(id).pipe(delay(1000)) // delay to mimic network
}