RXJS缓冲区转换,但立即需要初始值

RXJS Buffer Transform but want initial value immediately


假设"立即具有当前值"是指"第一个值一旦发出就立即",则可以将第二个元素缓冲到最后一个元素,然后合并到第一个元素中:

1
2
3
4
5
6
7
// source$: Observable< T >
const pub_source$ = source$.publish();
Observable.merge(
  pub_source$.take(1).map(first => [first]),
  pub_source$.skip(1).buffer(Observable.interval(X))
);
pub_source$.connect();

源需要很冷,以便take(1)skip(1)涉及相同的元素,因此我们使用publish。第一个元素也被包装以保持输出类型T[]一致。


使用zip运算符有一种更简单的方法,请参阅Learnrxjs中的灯泡注释。

Combined with interval or timer, zip can be used to time output from another source!

1
2
3
4
5
6
// Useful for slow source that emits at around the same rate as interval
// but suffers back-pressure with fast-emitting source

const interval = 1000
const output = Observable.zip(source, Observable.timer(0, interval))
  .map(x => x[0])

Observable.timer"调节"源的输出。请注意,计时器的第一个参数设置第一次发射的延迟。

工作示例:CodePen

脚注
我刚刚意识到,如果每秒有很多事件,这会产生背压(累积未发射的值),因此buffer是使用快速发射源的更好方法。

1
2
3
4
// Buffered version for fast source
const output2 = source.buffer(Observable.timer(0, interval))
  .filter(x => x.length)            // filter out empty buffer emits
  .flatMap(x => Observable.from(x)) // optional, converts array back to single emits