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$
吗?