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