使用 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(...)
。
我正在尝试检测何时在短 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(...)
。