我正在努力使用Observables创建一个倒数计时器,http://reactivex.io/documentation/operators/timer.html的示例似乎不起作用。在此特定示例中,与timerInterval相关的错误不是从计时器返回的Observable的函数。
我也一直在尝试其他方法,我提出的最好的方法是:
Observable.interval(1000).take(10).subscribe(x => console.log(x));
这里的问题是它从0到10计数,我想要一个倒数计时器,例如10,9,8 ... 0
我也试过这个,但是对于Observable类型
,timer
不存在
Observable.range(10, 0).timer(1000).subscribe(x => console.log(x));
同样,它根本不产生任何输出。
Observable.range(10, 0).debounceTime(1000).subscribe(x => console.log(x));
澄清我需要帮助ReactiveX的RxJS实现,而不是MircoSoft版本。
答案 0 :(得分:23)
你走在正确的轨道上 - 你的问题是timer
在原型上不存在(从而在Observable.range()
上),但是在Observable上(参见RxJS docs)。即jsbin
const start = 10;
Rx.Observable
.timer(100, 100) // timer(firstValueDelay, intervalBetweenValues)
.map(i => start - i)
.take(start + 1)
.subscribe(i => console.log(i));
// or
Rx.Observable
.range(0, start + 1)
.map(i => start - i)
.subscribe(i => console.log(i));
答案 1 :(得分:1)
使用间隔,允许您指定一秒钟的时间
const time = 5 // 5 seconds
var timer$ = Rx.Observable.interval(1000) // 1000 = 1 second
timer$
.take(time)
.map((v)=>(time-1)-v) // to reach zero
.subscribe((v)=>console.log('Countdown', v))
答案 2 :(得分:0)
我是take...()
的爱人,所以我按如下方式使用takeWhile()
(RxJS 6.x.x,以ES6方式)
import {timer} from 'rxjs';
import {takeWhile, tap} from 'rxjs/operators';
let counter = 10;
timer(1000, 1000) //Initial delay 1 seconds and interval countdown also 1 second
.pipe(
takeWhile( () => counter > 0 ),
tap(() => counter--)
)
.subscribe( () => {
console.log(counter);
} );
答案 3 :(得分:0)
如果您不想在开始时间依赖变量,请使用<div class="Container" [id]="id">
<img *ngFor="let item of data" [src]="item.url" (click) ="text=item.text">
</div>
<!--here show the variable "text"-->
<div class="text">{{text}}</div>
,timer
和scan
,takeWhile
中的第三个参数是起始数字
scan
答案 4 :(得分:0)
我的带有显示时间的倒计时功能:
import { Observable, timer, of, interval } from "rxjs";
import { map, takeWhile, take } from "rxjs/operators";
function countdown(minutes: number, delay: number = 0) {
return new Observable<{ display: string; minutes: number; seconds: number }>(
subscriber => {
timer(delay, 1000)
.pipe(take(minutes * 60))
.pipe(map(v => minutes * 60 - 1 - v))
.pipe(takeWhile(x => x >= 0))
.subscribe(countdown => { // countdown => seconds
const minutes = Math.floor(countdown / 60);
const seconds = countdown - minutes * 60;
subscriber.next({
display: `${("0" + minutes.toString()).slice(-2)}:${("0" + seconds.toString()).slice(-2)}`,
minutes,
seconds
});
if (seconds <= 0 && minutes <= 0) {
subscriber.complete();
}
});
});
}
countdown(2).subscribe(next => {
document.body.innerHTML = `<pre><code>${JSON.stringify(next, null, 4)}</code></pre>`;
});
输出即:
{
"display": "01:56",
"minutes": 1,
"seconds": 56
}
答案 5 :(得分:0)
这个例子对我有用:)
顺便说一句,使用 takeWhile(val => val >= 0)
而不是 take(someNumber)
可能有意义,但它会检查 -1 然后才完成...... 1 秒太晚了。
下面的示例将发出 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0。从 10 开始到 0 立即结束似乎微不足道,但对我来说却相当棘手。
>const counter$ = interval(1000); // rxjs creation operator - will fire every second
const numberOfSeconds = 10;
counter$.pipe(
scan((accumulator, _current) => accumulator - 1, numberOfSeconds + 1),
take(numberOfSeconds + 1),
// optional
finalize(() => console.log(
'something to do, if you want to, when 0 is emitted and the observable completes'
))
)
这将做同样的事情:
counter$.pipe(
scan((accumulator, current) => accumulator - 1, numberOfSeconds),
startWith(numberOfSeconds), // scan will not run the first time!
take(numberOfSeconds + 1),
// optional
finalize(() => console.log(
'something to do, if you want to, when 0 is emitted and the observable completes'
))
)
当然,您可以进行很多更改。例如,您可以在 mapTo(-1)
之前scan
,然后写入 accumulator + current
,current
将为 -1 .
答案 6 :(得分:0)
我还需要一个倒数的间隔,所以我尝试了这个解决方案:
// * startPoint => Value of timer continuing to go down
countDown(startPoint: number) {
// * Fire Every Second
const intervalObs = interval(1000);
// * Shrink intervalObs subscription
const disposeInterval = intervalObs.pipe(take(startPoint));
// * Fire incremental number on every second
disposeInterval.subscribe((second) => {
this.countDownOnRetry = startPoint - second;
});
}