[6a3a178] | 1 |
|
---|
| 2 | import { Observable } from '../Observable';
|
---|
| 3 | import { async } from '../scheduler/async';
|
---|
| 4 | import { SchedulerLike, OperatorFunction } from '../types';
|
---|
| 5 | import { scan } from './scan';
|
---|
| 6 | import { defer } from '../observable/defer';
|
---|
| 7 | import { map } from './map';
|
---|
| 8 |
|
---|
| 9 | /**
|
---|
| 10 | *
|
---|
| 11 | * Emits an object containing the current value, and the time that has
|
---|
| 12 | * passed between emitting the current value and the previous value, which is
|
---|
| 13 | * calculated by using the provided `scheduler`'s `now()` method to retrieve
|
---|
| 14 | * the current time at each emission, then calculating the difference. The `scheduler`
|
---|
| 15 | * defaults to {@link asyncScheduler}, so by default, the `interval` will be in
|
---|
| 16 | * milliseconds.
|
---|
| 17 | *
|
---|
| 18 | * <span class="informal">Convert an Observable that emits items into one that
|
---|
| 19 | * emits indications of the amount of time elapsed between those emissions.</span>
|
---|
| 20 | *
|
---|
| 21 | * ![](timeinterval.png)
|
---|
| 22 | *
|
---|
| 23 | * ## Examples
|
---|
| 24 | * Emit inteval between current value with the last value
|
---|
| 25 | *
|
---|
| 26 | * ```ts
|
---|
| 27 | * const seconds = interval(1000);
|
---|
| 28 | *
|
---|
| 29 | * seconds.pipe(timeInterval())
|
---|
| 30 | * .subscribe(
|
---|
| 31 | * value => console.log(value),
|
---|
| 32 | * err => console.log(err),
|
---|
| 33 | * );
|
---|
| 34 | *
|
---|
| 35 | * seconds.pipe(timeout(900))
|
---|
| 36 | * .subscribe(
|
---|
| 37 | * value => console.log(value),
|
---|
| 38 | * err => console.log(err),
|
---|
| 39 | * );
|
---|
| 40 | *
|
---|
| 41 | * // NOTE: The values will never be this precise,
|
---|
| 42 | * // intervals created with `interval` or `setInterval`
|
---|
| 43 | * // are non-deterministic.
|
---|
| 44 | *
|
---|
| 45 | * // {value: 0, interval: 1000}
|
---|
| 46 | * // {value: 1, interval: 1000}
|
---|
| 47 | * // {value: 2, interval: 1000}
|
---|
| 48 | * ```
|
---|
| 49 | *
|
---|
| 50 | * @param {SchedulerLike} [scheduler] Scheduler used to get the current time.
|
---|
| 51 | * @return {Observable<{ interval: number, value: T }>} Observable that emit infomation about value and interval
|
---|
| 52 | * @method timeInterval
|
---|
| 53 | */
|
---|
| 54 | export function timeInterval<T>(scheduler: SchedulerLike = async): OperatorFunction<T, TimeInterval<T>> {
|
---|
| 55 | return (source: Observable<T>) => defer(() => {
|
---|
| 56 | return source.pipe(
|
---|
| 57 | // TODO(benlesh): correct these typings.
|
---|
| 58 | scan(
|
---|
| 59 | ({ current }, value) => ({ value, current: scheduler.now(), last: current }),
|
---|
| 60 | { current: scheduler.now(), value: undefined, last: undefined }
|
---|
| 61 | ) as any,
|
---|
| 62 | map<any, TimeInterval<T>>(({ current, last, value }) => new TimeInterval(value, current - last)),
|
---|
| 63 | );
|
---|
| 64 | });
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | // TODO(benlesh): make this an interface, export the interface, but not the implemented class,
|
---|
| 68 | // there's no reason users should be manually creating this type.
|
---|
| 69 |
|
---|
| 70 | /**
|
---|
| 71 | * @deprecated exposed API, use as interface only.
|
---|
| 72 | */
|
---|
| 73 | export class TimeInterval<T> {
|
---|
| 74 | constructor(public value: T, public interval: number) {}
|
---|
| 75 | }
|
---|