rxjs
Version:
Reactive Extensions for modern JavaScript
95 lines (84 loc) • 2.66 kB
text/typescript
import { IScheduler } from '../Scheduler';
import { Action } from '../scheduler/Action';
import { Observable } from '../Observable';
import { Subscriber } from '../Subscriber';
import { TeardownLogic } from '../Subscription';
interface PairsContext<T> {
obj: Object;
keys: Array<string>;
length: number;
index: number;
subscriber: Subscriber<Array<string | T>>;
}
function dispatch<T>(this: Action<PairsContext<T>>, state: PairsContext<T>) {
const {obj, keys, length, index, subscriber} = state;
if (index === length) {
subscriber.complete();
return;
}
const key = keys[index];
subscriber.next([key, obj[key]]);
state.index = index + 1;
this.schedule(state);
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
export class PairsObservable<T> extends Observable<Array<string | T>> {
private keys: Array<string>;
/**
* Convert an object into an observable sequence of [key, value] pairs
* using an optional IScheduler to enumerate the object.
*
* @example <caption>Converts a javascript object to an Observable</caption>
* var obj = {
* foo: 42,
* bar: 56,
* baz: 78
* };
*
* var source = Rx.Observable.pairs(obj);
*
* var subscription = source.subscribe(
* function (x) {
* console.log('Next: %s', x);
* },
* function (err) {
* console.log('Error: %s', err);
* },
* function () {
* console.log('Completed');
* });
*
* @param {Object} obj The object to inspect and turn into an
* Observable sequence.
* @param {Scheduler} [scheduler] An optional IScheduler to run the
* enumeration of the input sequence on.
* @returns {(Observable<Array<string | T>>)} An observable sequence of
* [key, value] pairs from the object.
*/
static create<T>(obj: Object, scheduler?: IScheduler): Observable<Array<string | T>> {
return new PairsObservable<T>(obj, scheduler);
}
constructor(private obj: Object, private scheduler?: IScheduler) {
super();
this.keys = Object.keys(obj);
}
protected _subscribe(subscriber: Subscriber<Array<string | T>>): TeardownLogic {
const {keys, scheduler} = this;
const length = keys.length;
if (scheduler) {
return scheduler.schedule(dispatch, 0, {
obj: this.obj, keys, length, index: 0, subscriber
});
} else {
for (let idx = 0; idx < length; idx++) {
const key = keys[idx];
subscriber.next([key, this.obj[key]]);
}
subscriber.complete();
}
}
}