Как сделать таймер обратного отсчета с помощью RxJS Observables?

Я пытаюсь создать таймер обратного отсчета с использованием 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.

Я также пробовал это, но timer не существует для типа Observable

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.

Ответ 1

Вы были на правильном пути - ваша проблема заключалась в том, что 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));

Ответ 2

С интервалом, позволяет указать, сколько секунд

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

Я - любитель 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);
  } );