如何在RXJS中实现背压轮询

时间:2018-04-05 20:06:59

标签: javascript rxjs observable reactive-programming

我想轮询一个响应缓慢的HTTP API,所以我不希望同时多次调用此API。

我想做的一个例子可能是:

const interval = Rx.Observable.interval(250).take(5); // Poll every 250ms

function simulateMaybeSlowHttpCall() {
  return interval.delay(500).take(1); // The service takes 500ms to answer
}

 interval
   .mergeMap(val =>simulateMaybeSlowHttpCall().map(x => val), 1) // max concurrent is 1
   .subscribe(val => console.log(val));

此处显示此代码 1 2 3 4 5

但我不想做无用的电话。 以上代码运行250 * 5 = 1250 ms,1次调用需要500ms,所以我想显示:

1 3 5

所以我的问题是:当设置并发到1(或任何其他值)时,如何丢弃所有未立即执行的调用?

JsFiddle:https://jsfiddle.net/zra3zxhs/63/

1 个答案:

答案 0 :(得分:2)

使用并发为1的mergeMap等同于concatMap。事实上,这就是concatMap is implemented的方式。这就是为什么示例中的每个间隔都会影响HTTP请求的原因:它们排队等等。

如果您希望避免在一个待处理的HTTP请求中启动或排队,您可以使用exhaustMap

interval
  .exhaustMap(val => simulateMaybeSlowHttpCall().map(x => val))
  .subscribe(val => console.log(val));

当使用exhaustMap时,它会收到的任何next通知都会被忽略,直到内部observable(HTTP请求)完成。