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

RXJS缓冲区转换,但需要立即获得初始值,rxjs,Rxjs,根据,缓冲区转换将在发出任何值之前等待延迟。我想要的是立即获取当前值,然后仅每X秒更新一次 我还不能用rxjs实现这一点。最接近的方法是绑定可观察对象,然后在缓冲区超时发生后使用setTimeout函数重新绑定。这会产生一个副作用,即在发出当前值之前清除X秒的当前值 有什么想法吗 谢谢 假设“当前值立即”是指“第一个值一旦发出”,则可以将第二个元素缓冲到最后一个元素,并合并到第一个元素中: // source$: Observable<T> const pub_source$ = s

根据,缓冲区转换将在发出任何值之前等待延迟。我想要的是立即获取当前值,然后仅每X秒更新一次

我还不能用rxjs实现这一点。最接近的方法是绑定可观察对象,然后在缓冲区超时发生后使用setTimeout函数重新绑定。这会产生一个副作用,即在发出当前值之前清除X秒的当前值

有什么想法吗

谢谢

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

// 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();
//source$:可观察
const pub_source$=source$.publish();
可观察的合并(
pub_source$.take(1).map(first=>[first]),
pub_source$.skip(1).buffer(可观察的间隔(X))
);
pub_source$.connect();
源代码需要是冷的,以便
take(1)
skip(1)
与同一元素相关,因此我们使用
publish
。第一个元素也被包装,以保持输出类型的一致性。

假设“当前值立即”是指“第一个值一发出”,则可以将第二个元素缓冲到最后一个,并合并到第一个元素中:

// 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();
//source$:可观察
const pub_source$=source$.publish();
可观察的合并(
pub_source$.take(1).map(first=>[first]),
pub_source$.skip(1).buffer(可观察的间隔(X))
);
pub_source$.connect();

源代码需要是冷的,以便
take(1)
skip(1)
与同一元素相关,因此我们使用
publish
。第一个元素也被包装,以保持输出类型的一致性。

使用zip运算符有一种更简单的方法,请参见中的灯泡说明

与interval或timer相结合,zip可以用于对另一个源的输出计时

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

工作示例:

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

// 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

使用zip操作符有一种更简单的方法,请参见中的灯泡说明

与interval或timer相结合,zip可以用于对另一个源的输出计时

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

工作示例:

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

// 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

可能应该添加
.filter(x=>x.length)
来处理空发射您的假设是正确的。我希望第一个值在发出后立即生效,然后缓冲其余值。不过,我想先过滤掉空值。我发现这个答案忽略了缓冲区。我也尝试过用@RichardMatsen的定时器来代替间隔。我已经将我的source$设置为我的rxjs/store select。我已尝试将UI中显示的内容绑定到source$和pub_source$,但在每种情况下,缓冲区似乎都不起作用。@MarkDeVerno您能否更具体地说明缓冲区不起作用的原因?检查以验证这是否是预期的行为。(留下空数组以显示计时)@concat缓冲区似乎被忽略了,这就是我的意思;更新立即发生。事实证明,我绑定不正确,因为我将uiBinding设置为发布的内容(而不是可观察的内容)。在解决这个问题后,您的解决方案按照我的预期工作。我根据RichardMatsen的解决方案组合了过滤器,然后需要添加一个平面图,因为我的观察对象是一个数组。非常感谢你!编辑:这是我的建议,我可能应该添加
.filter(x=>x.length)
来处理空发射。您的假设是正确的。我希望第一个值在发出后立即生效,然后缓冲其余值。不过,我想先过滤掉空值。我发现这个答案忽略了缓冲区。我也尝试过用@RichardMatsen的定时器来代替间隔。我已经将我的source$设置为我的rxjs/store select。我已尝试将UI中显示的内容绑定到source$和pub_source$,但在每种情况下,缓冲区似乎都不起作用。@MarkDeVerno您能否更具体地说明缓冲区不起作用的原因?检查以验证这是否是预期的行为。(留下空数组以显示计时)@concat缓冲区似乎被忽略了,这就是我的意思;更新立即发生。事实证明,我绑定不正确,因为我将uiBinding设置为发布的内容(而不是可观察的内容)。在解决这个问题后,您的解决方案按照我的预期工作。我根据RichardMatsen的解决方案组合了过滤器,然后需要添加一个平面图,因为我的观察对象是一个数组。非常感谢你!编辑:值得注意的是,我们答案的行为非常不同。以这种方式使用的
buffer
zip
都会延迟第一次发射,如果它比间隔快,并且使用
zip
并不是真正的“缓冲”,而是将发射速率限制在1/间隔。正确的,我注意到了同样的情况,并添加了一个缓冲版本。我还注意到zip版本(IMHO)更接近马克的描述,虽然这可能需要一些澄清-即,是否可以接受每个间隔发射多个项目?这个缓冲区版本非常接近我所寻找的。为了澄清(这里因为我还不能编辑我的答案),我正在寻找第一个非空值,然后每个间隔发出多个项目是可以接受的。因此,在我链接的文档中,我想发出['