如何在RxJS5中应用定时背压?

时间:2018-01-29 03:23:16

标签: javascript rxjs observable rxjs5 reactivex

想象一下,我有以下代码:

addEventListener("click", function completeW() {
    winit();
    getScript();
    wikiCall(); /* <== Here is the only place wikiCall is invoked and you pass it no arguments. */
}, false);

这会立即输出结果。现在,我如何在每条消息之间设置一个定时延迟作为背压方式(注意我不需要缓冲区;相反,我想要let a = Rx.Observable.of(1, 2, 3) let b = Observable.zip(a, a, (a, b) => a + b) b.forEach(t => console.log(t)) 和{{1成为 Cold Observables ),如:

a

得到完全相同的答案:

b

替代方案:如果RxJS不支持背压(某些可观测量的pull拉机制),那么如何在不耗尽资源的情况下创建无限生成器呢?

备选方案2:其他支持拉取和推送机制的JS框架?

2 个答案:

答案 0 :(得分:3)

如果RxJS 5.x背压不支持,但在4.x版本中有例如pausable operator。它仅适用于热观察。有关4.xhere的背压的更多信息(特别是在底部获取战利品和RxJS相关描述)。

这条Erik Meijer的推文可能有点争议但相关:https://twitter.com/headinthebox/status/774635475071934464

对于您自己实施的背压机制,您需要具有双向通信通道,可以使用2个主题轻松创建 - 每个通道一个。基本上使用next发送邮件,.subscribe列出到另一端。

创建一个生成器也是可行的 - 再次使用主题在基于推拉和拉动的世界之间架起桥梁。下面是用于生成斐波纳契数的示例性实现。

const fib = () => {
  const n = new Rx.Subject()
  const f = n
    .scan(c => ({ a: c.b, b: c.b + c.a }), { a: 0, b: 1 })
    .map(c => c.a)
    
  return {
    $: f,
    next: () => n.next()
  }
}

const f = fib()

f.$.subscribe(n => document.querySelector('#r').innerHTML = n)
Rx.Observable.fromEvent(document.querySelector('#f'), 'click')
  .do(f.next)
  .subscribe()
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>

<button id='f'>NEXT FIBONACCI</button>

<div id='r'>_?_<div>

另一个可能对您感兴趣的js库是https://github.com/ubolonton/js-csp - 没有使用它,所以不确定它是如何处理背压的。

答案 1 :(得分:0)

这个想法是将前一个完成执行的时间等待一个接一个地排队Fiddle

let a = Rx.Observable.of(1, 2, 3);
let b = Rx.Observable.zip(a, a, (a, b) => a + b);

// getting values into array
var x = [];
b.forEach(t => x.push(t));

var takeEvery = function(msec,items,action,index=0){
  if(typeof(action) == "function")
    if(index<items.length)
        setTimeout(
        function(item,ind){
          action(item);
          takeEvery(msec,items,action,ind);
        },msec, items[index],++index);

};

// queueing over time
takeEvery(1000,x, function(item){
    console.log(item);
});