RxJS鼠标活动跟踪

时间:2018-06-04 06:21:58

标签: rxjs rxjs5

我正在开发用户活动跟踪系统并尝试实现下一个目标:

  1. 用户开始移动鼠标两秒后抓住mousemove事件一次。
  2. 用户完成移动鼠标两秒后抓住片刻。
  3. 我有下一个流:

    const activityStream$ = Rx.Observable.fromEvent(document, 'mousemove');
    
    const enterActivityStream$ = activityStream$.throttleTime(1000).skip(2);
    
    const finishActivityStream$ = activityStream$.debounceTime(2000);
    

    另外它们按预期工作,我想将它们组合起来,因此它们将以重复的方式工作。

    E.g: 用户开始移动鼠标,观察者在两秒后获得关于该事件的事件(或至少do运算符),然后用户完成移动鼠标并且观察者也会收到通知。如果用户再次开始移动鼠标,则重复此例程。

    我在Example RxJS Observable when mouse or click activity Re-starts找到了类似的问题,但解决方案似乎很复杂,并且无法按预期工作。 (lastact$流会触发两次,它应该触发一次)。

    拜托,任何人都可以给我一个关于如何实现这一目标的线索?谢谢!

3 个答案:

答案 0 :(得分:1)

我认为你只能使用merge

Observable.merge(
    enterActivityStream$, 
    activityStream$, 
    finishActivityStream$,
  )
  .subscribe(...)

根据您的描述,您似乎只想在2秒间隔后开始发出任何值,因此您也可以这样做:

enterActivityStream$
  .take(1)
  .mergeMap(() => activityStream$)
  .takeUntil(finishActivityStream$)
  .repeat()
  .subscribe(...);

答案 1 :(得分:0)

感谢Martin。最后,我能够达到理想的解决方案。它有效,但我将不胜感激任何改进此代码的建议。

const activityStream$ = Rx.Observable.fromEvent(document, 'mousemove').mapTo(true);

const enterActivityStream$ = activityStream$
  .throttleTime(2000)
  .skip(1) // Skip first event to avoid accidental touches
  .takeUntil(activityStream$.debounceTime(100)) // reset after 100 milliseconds of inactivity
  .repeat(); // and then repeat

const finishActivityStream$ = activityStream$.debounceTime(2000).mapTo(false);


enterActivityStream$
  .mergeMap(() => activityStream$.merge(finishActivityStream$)) 
  .distinctUntilChanged()
  .take(2) // Take true (activity started) and then false (activity stopped).
  .repeat() // And then repeat
  .subscribe(active => {
    if (active) {
      console.log('Notify about activity being started');
    } else {
      console.log('Notify about activity being stopped');
    }
  })

答案 2 :(得分:0)

如果您仍在寻找stackblitz上的此解决方案,

import { interval, fromEvent } from 'rxjs';
import { throttle, tap, debounceTime, delay } from 'rxjs/operators';

const source = fromEvent(document, 'mousemove');

const untilIsActiv = source.pipe(
  debounceTime(2000),
  tap(val => console.log(`caugth inactivity`))
);

const example = source
  .pipe(
    delay(2000),
    throttle(val => untilIsActiv)
  );


const subscribe = example.subscribe(val => console.log('caugth event'));