问题
I'm struggling to create a countdown timer using Observables, the examples at http://reactivex.io/documentation/operators/timer.html do not seem to work. In this specific example the error related to timerInterval not being a function of the Observable returned from timer.
I have also been experimenting with other approaches and the best I've come up with is:
Observable.interval(1000).take(10).subscribe(x => console.log(x));
The problem here is it counts up from 0 to 10 and I want a countdown timer e.g. 10,9,8...0.
I've also tried this but the timer does not exist for type Observable
Observable.range(10, 0).timer(1000).subscribe(x => console.log(x));
As well as, which produces no output at all.
Observable.range(10, 0).debounceTime(1000).subscribe(x => console.log(x));
To clarify I need help with ReactiveX's RxJS implementation, not the MircoSoft version.
回答1:
You were on the right track - your problem was that timer does not exist on the prototype (and thereby on Observable.range())but on Observable (see the RxJS docs). I.e. 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));
回答2:
With interval, allows you to specify how long a second is
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))
回答3:
I am the take...() lover, so I am using takeWhile() as follow ( RxJS 6.x.x, in ES6 way )
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);
} );
回答4:
Using timer, scan and takeWhile if you don't want to depend on a variable for your starting time, the 3rd argument in scan is the starting number
timer$ = timer(0, 1000).pipe(
scan(acc => --acc, 120),
takeWhile(x => x >= 0)
);
Check it out on Stackblitz
来源:https://stackoverflow.com/questions/34921555/how-to-make-countdown-timer-with-rxjs-observables