带rxjs的倒计时定时器



我需要通过单击按钮来启动计时器。但这并没有发生

public startTimerRxjs() {
this.timeLeft$ = timer(0, 1000).pipe(
takeWhile(() => this.timeLeft > 0),
map(() => {
this.timeLeft--;
this.changeDetRef.detectChanges();
return this.timeLeft;
})
);
}

您可以使用一个变量来倒计时您的发射。在rxjs中,变量(状态(由扫描运算符处理。有了takeWhile,你就可以停止流的排放。

const { timer } = rxjs;
const { scan, takeWhile, asyncScheduler } = rxjs.operators
const result$ = timer(0, 1000).pipe(
scan(ticks => --ticks, 5),
takeWhile(v => v >= 0)
);
result$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>

为了重用它并添加更多的注释,我创建了一个名为countdown的自定义运算符来封装您的问题。

const { timer } = rxjs;
const { scan, takeWhile, asyncScheduler } = rxjs.operators
/*
* dueTime, intervalOrScheduler, schedule: timer api - https://rxjs.dev/api/index/function/timer
* maxTicks: describe the max timer emits
*/
const countdown = (dueTime = 0, intervalOrScheduler, maxTicks = 0, scheduler = asyncScheduler) => timer(dueTime, intervalOrScheduler).pipe(
// start with the maxTicks value and decrease every emit
scan(remainingTicks => --remainingTicks, maxTicks),
// stop emitting when maxTicks reaches -1
takeWhile(v => v >= 0)
);
const result$ = countdown(0, 1000, 5)
result$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>

要么在组件中使用异步管道(不使用按钮来触发它(,要么订阅代码:

<div>{{ timeLeft | async }}</div>

或:

this.timeLeft$ = timer(0, 1000)
.pipe(
takeWhile(() => this.timeLeft > 0),
map(() => {
this.timeLeft--;
this.changeDetRef.detectChanges();
return this.timeLeft;
})
).subscribe();

最新更新