我正在开发用户活动跟踪系统并尝试实现下一个目标:
mousemove
事件一次。我有下一个流:
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$
流会触发两次,它应该触发一次)。
拜托,任何人都可以给我一个关于如何实现这一目标的线索?谢谢!
答案 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'));