typescript 在rxjs中创建OnIdle

r3i60tvu  于 2023-04-13  发布在  TypeScript
关注(0)|答案(1)|浏览(173)

在学习rxJS时,我有以下代码,用于检查浏览器窗口中是否有活动,如鼠标移动,单击或使用键盘。

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.我们将监视键盘、鼠标和间隔事件
1.如果没有鼠标或键盘事件发生,但间隔触发,则浏览器处于空闲状态,我们将触发onIdle
1.如果任何鼠标或键盘事件发生在间隔事件之前,浏览器不会空闲,我们将不会触发任何事件
我如何实现这个逻辑,或者反转我当前代码的工作。

wbgh16ku

wbgh16ku1#

您可以尝试使用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()

  }, [])
}

相关问题