RxJS鼠标活动跟踪

RxJS鼠标活动跟踪,rxjs,rxjs5,Rxjs,Rxjs5,我正在开发用户活动跟踪系统,并尝试实现下一个目标: 捕获mousemove事件两秒钟后,用户开始移动鼠标 在用户完成鼠标移动两秒钟后捕捉片刻 我有以下几条流: const activityStream$ = Rx.Observable.fromEvent(document, 'mousemove'); const enterActivityStream$ = activityStream$.throttleTime(1000).skip(2); const finishActivityStr

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

  • 捕获
    mousemove
    事件两秒钟后,用户开始移动鼠标
  • 在用户完成鼠标移动两秒钟后捕捉片刻
  • 我有以下几条流:

    const activityStream$ = Rx.Observable.fromEvent(document, 'mousemove');
    
    const enterActivityStream$ = activityStream$.throttleTime(1000).skip(2);
    
    const finishActivityStream$ = activityStream$.debounceTime(2000);
    
    它们分别按预期工作,我希望将它们结合起来,这样它们将以重复的方式工作

    例如: 用户开始移动鼠标,两秒钟后,观察者获得关于该事件的事件(或至少
    do
    operator),然后用户完成移动鼠标,观察者也得到关于该事件的通知。如果用户再次开始移动鼠标,则重复此例程

    我在那个里发现了类似的问题,但解决方案似乎很复杂,并没有达到预期效果。(
    lastact$
    流触发两次,而它应该触发一次)


    请问,有谁能给我一个关于如何实现这一点的线索吗?谢谢

    我想你可以使用
    merge

    Observable.merge(
        enterActivityStream$, 
        activityStream$, 
        finishActivityStream$,
      )
      .subscribe(...)
    
    根据您的描述,您似乎希望仅在2s间隔后开始发射任何值,因此您也可以执行以下操作:

    enterActivityStream$
      .take(1)
      .mergeMap(() => activityStream$)
      .takeUntil(finishActivityStream$)
      .repeat()
      .subscribe(...);
    
    多亏了。最后,我终于找到了理想的解决方案。它是有效的,但我将感谢任何建议,以改善这段代码

    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');
        }
      })
    
    如果您仍在寻找,请在上查看此解决方案

    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'));
    

    谢谢你的回复,马丁。这两种情况的问题都是跳过(2)只在第一次生效。如果我重复此例程,
    skip(2)
    不再工作,因此
    enterActivityStream$
    立即开始分派(公平地说,已经跳过了两个第一个事件)。我需要重新启动
    enterActivityStream$
    或以某种方式重新启动整个序列。像这样的事情可能吗?当
    strottletime
    之后,skip(2)应该在那里做什么呢?当您在描述中提到“在用户开始移动鼠标两秒钟后捕获鼠标移动事件一次”时,您似乎可以使用
    .throttleTime(2000)
    skip(2)
    应该在前两秒钟内跳过鼠标移动。想象一下,如果用户不小心触碰了鼠标。我不想跟踪这种活动。这就是为什么我只想在鼠标移动两秒钟后开始跟踪。如果我做了
    throttleTime(2000)
    意外触碰还是会过去的。这是不受欢迎的行为。我觉得解决这个问题一定很容易,但我不知道怎么处理。对我来说,似乎我需要适当的鼠标移动过滤,但我不知道如何做到这一点。请参阅我的更新。因此,
    enterActivityStream$
    只有一个发射,然后它继续从
    activityStream$
    发射,直到
    .takeUntil(finishActivityStream$)
    。完成后,它会使用
    repeat()
    重复整个过程,看起来非常接近。现在唯一的问题是我无法将
    finishActivityStream$
    发送到
    subscribe
    。你能看看这个吗?我可以在那里包括
    finishActivityStream$
    吗?