Cancel an observable created with “fromEvent” and switch to a new one

…衆ロ難τιáo~ 提交于 2019-12-13 15:35:25

问题


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 ?


回答1:


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



回答2:


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



来源:https://stackoverflow.com/questions/56574634/cancel-an-observable-created-with-fromevent-and-switch-to-a-new-one

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!