在rxjs中创建OnIdle



在学习rxJS的同时,我有以下一段代码,用于检查浏览器窗口上是否有活动,如鼠标移动,单击或使用键盘。把它看作onIdle

的反面
import { fromEvent, throttle, debounce, interval, merge } from 'rxjs';
import { map } from 'rxjs/operators';
function useActivated(fn: (event: string) => void) {
useEffect(()=>{
const clicks = fromEvent(document, 'click')
const move = fromEvent(window, 'mousemove')
const keys = fromEvent(window, 'keypress')
const merged = merge(
keys.pipe(map((x) => 'key')),
clicks.pipe(map((x) => 'mouse click')),
move.pipe(map((x) => 'mouse move'))
)
const final = merged.pipe(throttle(() => interval(1000)))
const subscription = final.subscribe((x) => fn(x));
return () => subscription.unsubscribe()
}, [])
}
useActivated((x) => console.log(x));

我希望能够创建一个函数useOnIdle(),其输出与此相反。逻辑是,

  1. 我们将监控键盘,鼠标和间隔事件
  2. 如果没有鼠标或键盘事件发生,但间隔触发,则浏览器空闲,我们触发onIdle
  3. 如果任何鼠标或键盘事件发生在间隔事件之前,浏览器不是空闲的,我们将不会触发任何事件

我如何实现这个逻辑,或者反转我当前代码的工作。

您可以尝试使用bufferTime操作符而不是throttlefilter,如下所示

function useIdle(fn: (event: string) => void) {
useEffect(()=>{
const clicks = fromEvent(document, 'click')
const move = fromEvent(window, 'mousemove')
const keys = fromEvent(window, 'keypress')
const merged = merge(
keys.pipe(map((x) => 'key')),
clicks.pipe(map((x) => 'mouse click')),
move.pipe(map((x) => 'mouse move'))
)
const final = merged.pipe(
// buffer the notifications of merged observable over an interval
bufferTime(1000),
// if the buffer is empty, then the system has been idle
filter(vals => vals.length === 0),
map(() => 'idle')
)
const subscription = final.subscribe((x) => fn(x));
return () => subscription.unsubscribe()
}, [])
}