Reputation: 7144
My goal is to emit "hi again" in 1 second interval until a key is pressed and continue whenever there is a mouse click. Here is my code:
import { of, fromEvent, interval } from 'rxjs';
import { map, tap, takeUntil,take, repeatWhen, shareReplay, switchMap , takeLast} from 'rxjs/operators';
const fromKeyUp$ = fromEvent(window, 'keyup').pipe(tap(_=> console.log('keyup')));
const fromMouseUp$ = fromEvent(window, 'mouseup').pipe(tap(_=> console.log('mouseup')));
const source = interval(1000).pipe(tap(_ => {
console.log('hi again');
}), takeUntil(fromKeyUp$), repeatWhen(() => fromMouseUp$));
source.subscribe();
The problem is that when there are too many mouse clicks => "hi again" emits more times than usual.
I've tried to use switchMap
to cancel previous mouseup's like:
const fromMouseUp$ = fromEvent(window, 'mouseup').pipe(switchMap(() => tap(_=> console.log('mouseup'))));
but it didn't work as tap is not meant for creation.
Any ideas ?
Upvotes: 2
Views: 1396
Reputation: 11380
The below code will toggle value through by mouseup or stopped by keyup, you can put your handling logic inside mergeMap
const fromKeyUp$ = fromEvent(window, 'keyup').pipe(tap(_=> console.log('keyup')),mapTo(false));
const fromMouseUp$ = fromEvent(window, 'mouseup').pipe(tap(_=> console.log('mouseup')),mapTo(true));
const timeInterval=interval(1000).pipe(
tap(_ => {
console.log('hi again');
}))
const source=combineLatest(timeInterval,merge(fromMouseUp$,fromKeyUp$).pipe(startWith(true))
).pipe(
mergeMap(([value,through])=>through?
of(value):never()),distinctUntilChanged()
)
source.subscribe(console.log);
another simplier alternative with windowToggle
interval(2000).pipe(
windowToggle(fromMouseUp$.pipe(startWith(true)),()=>fromKeyUp$),
switchMap(obs=>obs)
).subscribe(console.log)
both solution won't interrupt the source interval
Upvotes: 1
Reputation: 96969
I think you can just reorder the operators and use switchMap
to cancel the previous interval
:
fromMouseUp$.pipe(
startWith(null),
switchMap(() => interval(1000).pipe(
takeUntil(fromKeyUp$),
)),
).subscribe();
Upvotes: 3