1 import { Observable } from '../Observable';
2 import { SchedulerAction, SchedulerLike } from '../types';
3 import { Subscriber } from '../Subscriber';
4 import { Subscription } from '../Subscription';
7 * Convert an object into an Observable of `[key, value]` pairs.
9 * <span class="informal">Turn entries of an object into a stream.</span>
11 * <img src="./img/pairs.png" width="100%">
13 * `pairs` takes an arbitrary object and returns an Observable that emits arrays. Each
14 * emitted array has exactly two elements - the first is a key from the object
15 * and the second is a value corresponding to that key. Keys are extracted from
16 * an object via `Object.keys` function, which means that they will be only
17 * enumerable keys that are present on an object directly - not ones inherited
18 * via prototype chain.
20 * By default these arrays are emitted synchronously. To change that you can
21 * pass a {@link SchedulerLike} as a second argument to `pairs`.
23 * @example <caption>Converts a javascript object to an Observable</caption>
25 * import { pairs } from 'rxjs';
35 * value => console.log(value),
37 * () => console.log('the end!')
47 * @param {Object} obj The object to inspect and turn into an
48 * Observable sequence.
49 * @param {Scheduler} [scheduler] An optional IScheduler to schedule
50 * when resulting Observable will emit values.
51 * @returns {(Observable<Array<string|T>>)} An observable sequence of
52 * [key, value] pairs from the object.
54 export function pairs<T>(obj: Object, scheduler?: SchedulerLike): Observable<[string, T]> {
56 return new Observable<[string, T]>(subscriber => {
57 const keys = Object.keys(obj);
58 for (let i = 0; i < keys.length && !subscriber.closed; i++) {
60 if (obj.hasOwnProperty(key)) {
61 subscriber.next([key, obj[key]]);
64 subscriber.complete();
67 return new Observable<[string, T]>(subscriber => {
68 const keys = Object.keys(obj);
69 const subscription = new Subscription();
71 scheduler.schedule<{ keys: string[], index: number, subscriber: Subscriber<[string, T]>, subscription: Subscription, obj: Object }>
72 (dispatch, 0, { keys, index: 0, subscriber, subscription, obj }));
79 export function dispatch<T>(this: SchedulerAction<any>,
80 state: { keys: string[], index: number, subscriber: Subscriber<[string, T]>, subscription: Subscription, obj: Object }) {
81 const { keys, index, subscriber, subscription, obj } = state;
82 if (!subscriber.closed) {
83 if (index < keys.length) {
84 const key = keys[index];
85 subscriber.next([key, obj[key]]);
86 subscription.add(this.schedule({ keys, index: index + 1, subscriber, subscription, obj }));
88 subscriber.complete();