[英]RxJS Pause timer Observable
I have done a small timer, with 3 buttons:我做了一个小计时器,有3个按钮:
start stop pause/resume (which I haven't done yet)开始停止暂停/恢复(我还没有完成)
here is my code so far:到目前为止,这是我的代码:
class StopwatchWidgetComponent {
private readonly _start$: Subject<void> = new Subject();
private readonly _stop$: Subject<void> = new Subject();
private readonly _paused$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
readonly counter$: Observable<number>;
constructor() {
this.counter$ = this._start$.pipe(
startWith(0), // trigger emission at launch
switchMap(() => timer(0, 1000).pipe(
takeUntil(this._stop$)
))
);
// Subscribe done later
}
start(): void {
this._start$.next();
}
stop(): void {
this._stop$.next();
}
togglePause(): void {
this._paused$.next(!this._paused$.getValue());
}
}
However, I didn't manage to use the _paused$
subject properly so far.但是,到目前为止,我还没有设法正确使用_paused$
主题。 By looking at github, I found a few topics about this subject:通过查看 github,我发现了一些关于这个主题的主题:
https://github.com/ReactiveX/rxjs/issues/1542 https://github.com/ReactiveX/rxjs/issues/1542
but I feel that in my case, I would need to get rid of the current timer observable, and trigger a new one starting from the value we stopped at when pausing (and thus having to store that value).但我觉得在我的情况下,我需要摆脱当前可观察的计时器,并从我们在暂停时停止的值开始触发一个新的计时器(因此必须存储该值)。 Any other operator could help me out here to not have to do that?任何其他操作员都可以在这里帮助我不必这样做吗?
I create a timer with observables a while back.不久前,我创建了一个带有 observables 的计时器。 Perhaps it will give you some insight?也许它会给你一些见解?
How does this work?这是如何运作的? The custom observable creates a stream that outputs the number on the stopwatch and is controlled by a separate stream (Here called control$
).自定义的 observable 创建了一个 stream 输出秒表上的数字,并由单独的 stream 控制(这里称为control$
)。
When control$
emits "START", the stopWatch starts, when it emits "STOP", the stopwatch stops, and when it emits "RESET" the stopwatch sets the counter back to zero.当control$
发出“START”时,秒表启动,当它发出“STOP”时,秒表停止,当它发出“RESET”时,秒表将计数器设置回零。 When control$
errors or completes, the stopwatch errors or completes.当control$
出错或完成时,秒表出错或完成。
function createStopwatch(control$: Observable<string>, interval = 1000): Observable<number>{
return defer(() => {
let toggle: boolean = false;
let count: number = 0;
const ticker = timer(0, interval).pipe(
map(x => count++)
);
const end$ = of("END");
return concat(
control$,
end$
).pipe(
catchError(_ => end$),
filter(control =>
control === "START" ||
control === "STOP" ||
control === "RESET" ||
control === "END"
),
switchMap(control => {
if(control === "START" && !toggle){
toggle = true;
return ticker;
}else if(control === "STOP" && toggle){
toggle = false;
return EMPTY;
}else if(control === "RESET"){
count = 0;
if(toggle){
return ticker;
}
}
return EMPTY;
})
);
});
}
If the control stream is going to be a subject, this is a good way to create the stopwatch.如果控件 stream 将成为主题,这是创建秒表的好方法。
function getStopWatch(interval: number = 1000): {
control$: Subject<string>,
display$: Observable<number>
} {
const control$ = new Subject<string>();
return {
control$,
display$: createStopwatch(control$, interval)
}
}
Stopwatch Object in Use:秒表 Object 使用中:
const watch = getStopWatch();
watch.display$.subscribe(/*Numbers emitted here every interval once started by control$*/);
watch.control$.next("START");
watch.control$.next("STOP");
watch.control$.next("RESET");
// Completing the control cleans up everything
watch.control$.complete();
createStopwatch(merge(
fromEvent(startBtn, 'click').pipe(mapTo("START")),
fromEvent(stopBtn, 'click').pipe(mapTo("STOP"))
fromEvent(resetBtn, 'click').pipe(mapTo("RESET"))
)).subscribe(seconds => {
secondsField.innerHTML = seconds % 60;
minuitesField.innerHTML = Math.floor(seconds / 60) % 60;
hoursField.innerHTML = Math.floor(seconds / 3600);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.