所以,今天我想出了如何实现这一点,但还有一个错误要修复(计数器在两秒后从 play 或 pause 开始,我还不知道为什么)。
这里是源代码
index.ts
import { interval, fromEvent, merge, empty } from "rxjs";
import { switchMap, mapTo, tap, startWith, scan } from "rxjs/operators";
// elem refs
const remainingLabel = document.getElementById("remaining");
const breakTimerDOM = document.getElementById("break-timer");
const pauseButton = document.getElementById("pause");
const resumeButton = document.getElementById("play");
const stopButton = document.getElementById("stop");
// streams
const resume$ = fromEvent(resumeButton, "click").pipe(
mapTo({ isCounting: true, isBlocked: false })
);
const pause$ = fromEvent(pauseButton, "click").pipe(
mapTo({ isCounting: false, isBlocked: false })
);
const stop$ = fromEvent(stopButton, "click").pipe(
mapTo({ isCounting: false, isBlocked: true, counter: 0, breakCounter: 0 }),
tap(() => empty())
);
const timer$ = merge(resume$, pause$, stop$).pipe(
startWith({
counter: 0,
breakCounter: 0,
isCounting: false,
isBlocked: true
}),
scan((state, curr) => ({ ...state, ...curr })),
switchMap(state => {
return !state.isBlocked
? interval(1000).pipe(
tap(() => {
const { isCounting, counter, breakCounter } = state;
if (isCounting) {
remainingLabel.innerHTML = counter.toString();
state.breakCounter = 0;
state.counter++;
} else {
breakTimerDOM.innerHTML = breakCounter.toString();
state.breakCounter++;
}
})
)
: empty();
})
);
timer$.subscribe();
index.html
<h4>
Time remaining: <span id="remaining">0</span>
</h4>
<h4>
Break timer: <span id="break-timer">0</span>
</h4>
<button id="pause">
Pause
</button>
<button id="play">
Play
</button>
<button id="stop">
Stop
</button>
你可以从这里https://stackblitz.com/edit/typescript-7z6hab?file=index.ts fork 源代码。