Rx:缓冲区具有可变的反压缓冲时间

时间:2017-12-27 02:51:25

标签: rxjs system.reactive

我和Rx玩了一点,但仍然认为自己对世界是新的。我有一个问题,我想知道我是否可以通过Rx解决它。我最初的用例是在C#中,但后来可能在JS中需要相同的(尽管如果答案中有任何代码片段,任何伪代码语言都可以)

目前我有一个客户端应用程序,它只是缓冲它创建的数据(事务),并每隔5秒发送到服务器。该数据可以包含许多单独的交易,例如它存储了许多,现在上线,所以我们想要向服务器发送数千个。当发送如上所述的许多时,8秒延迟和缓冲很好(数据已经被延迟了)。但是,当这个客户端连接时,我们实时创建一个事务(即只有1或2个单个事务),我希望能够立即发送这些事务,即不等待8秒。

所以它看起来与Rx buffer类似,可能与debounce交叉?我试图绘制一个大理石图来帮助解释使用高级图形包(而不是)绘画。

enter image description here

因此,要完成此操作,将收到第一个红色大理石并立即转发。接下来,黄色大理石也会立即转发,因为距离最后一块红色大理石已经过了1秒钟。

现在淡蓝色大理石,以及其他一些大理石,不到1秒,所以我们现在想要缓冲这些,因为我们不想垃圾网络可能有数千个请求 - 我们将在这里做的是缓冲5秒,然后发送许多我们已经缓冲,每5秒,直到这个“突发”结束。在此之后,我们希望返回发送任何其他“个人”请求。

它没有完全像上面那样,基本上我们想要

  • 单个交易(对连接客户端应用程序的用户输入),立即发送,(或一些非常小的延迟)

  • 检测我们何时开始获取许多交易,并开始这样做 “油门”,然后以较长的时间间隔(例如5或8秒)发送缓冲的批次

  • 不想扔掉任何交易(大理石),我想全部发送

我发现其他一些帖子类似,但与此不一样。

我已经想出了一些笨拙的“手动”方法(仅使用标准列表和各种计时器等),但是想知道这是否可以使用 Rx 来做一些这项工作,希望不那么容易出错?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我认为你已经选择了它,bufferdebounce作为缓冲触发器,

  

此客户端是,例如已连接

如果您想添加连接事件,您也可以将其合并到bufferTrigger



console.clear()

const source = new Rx.Subject();
const bufferTrigger = source.debounceTime(500);

source
  .buffer(bufferTrigger)
  .subscribe(console.log);

setTimeout(() => source.next('red'), 0);
setTimeout(() => source.next('yellow'), 1000);
setTimeout(() => source.next('lightblue'), 3000);
setTimeout(() => source.next('green'), 3100);
setTimeout(() => source.next('blue'), 3200);
setTimeout(() => source.next('pink'), 4000);

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
&#13;
&#13;
&#13;

在最后一次发射后5秒附加触发的示例

&#13;
&#13;
const source = new Rx.Subject();
const lastEmit = new Rx.Subject();
const maxDelayAfterLastEmit = lastEmit.delay(5000);
const bufferTrigger = source.debounceTime(500)
  .merge(maxDelayAfterLastEmit);

const emits = source
  .buffer(bufferTrigger)
  .do(x => lastEmit.next(x))
  .filter(x => x.length);

var start = new Date().getTime();
emits.subscribe(x => console.log((new Date().getTime() - start)/1000  + "s " + x));

setTimeout(() => source.next('red'), 0);
setTimeout(() => source.next('yellow'), 1000);
setTimeout(() => source.next('lightblue'), 3000);
setTimeout(() => source.next('green'), 3100);
setTimeout(() => source.next('blue1'), 3200);
setTimeout(() => source.next('blue2'), 3300);
setTimeout(() => source.next('blue3'), 3600);
setTimeout(() => source.next('pink1'), 4000);
setTimeout(() => source.next('pink2'), 4400);
setTimeout(() => source.next('pink3'), 4800);
setTimeout(() => source.next('pink4'), 5200);
setTimeout(() => source.next('pink5'), 5600);
setTimeout(() => source.next('pink6'), 6000);
setTimeout(() => source.next('pink7'), 6400);
setTimeout(() => source.next('pink8'), 6800);
setTimeout(() => source.next('pink9'), 7200);
setTimeout(() => source.next('pink10'), 7700);
setTimeout(() => source.next('pink11'), 8200);
setTimeout(() => source.next('pink12'), 8600);
setTimeout(() => source.next('pink13'), 9000);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
&#13;
&#13;
&#13;