使用 RXJS,我怎样才能观察到从第一次按下到时间结束 window 按下的按键?

With RXJS, how can I get an observable of keys pressed from the first press until the end of a time window?

我正在尝试检测何时在短 window 时间内发生多次按键。

我的尝试是:

fromEvent(window, 'keydown').pipe(
    bufferTime(200),
    filter(events => events.length > 1)
);

我的解决方案的问题是事件每 200 毫秒发出一次。这意味着如果用户在缓冲区 window 的末尾按下一个键,在下一个缓冲区 window 的开头按下另一个键,则不会捕获多个按键。

我想要的是缓冲区在第一次按键时启动,并在第一次按键后 200 毫秒发出。

理想情况下,我想再等 200 毫秒,然后再启动另一个缓冲区。

非常感谢收到任何建议。

编辑:我已经确定了以下内容。

const keydown$ = fromEvent(window, 'keydown').pipe(share());
const src$ = keydown$.pipe(
    buffer(
        keydown$.pipe(
            debounce(() =>
                timer(150)
            )
        )
    )
);

What I'd like instead is for the buffer to start on the first key press and to be emitted 200ms after the 1st keypress.

基于此,这里可能有一个解决方案:

const keydown$ = fromEvent(window, 'keydown').pipe(share());

const src$ = keydown$.pipe(
  buffer(
    concat(keydown$.pipe(take(1), ignoreElements()), timer(200)).pipe(repeat())
  ),
);

share() 将在数据消费者和数据生产者(keydown 事件)之间放置一个 Subject 实例。有了这个,源将不会被每个新订阅者订阅。

让我们仔细看看

concat(keydown$.pipe(take(1), ignoreElements()), timer(200)).pipe(repeat())

这样,计时器 (timer(200) 在第一个按键事件后启动。在 keydown$.pipe(take(1), ignoreElements()) 中,我们使用 ignoreElements,因为我们不希望缓冲区在第一个事件之后发出,而是仅在那些 200 毫秒通过后发出。

最后,repeat() 将被使用,因为传递给 concat 的两个 observable 最终将完成(这也表明累积事件将被发送的时刻)。 repeat() 将在完成后重新订阅 concat(...)