UNPKG

@reactivex/rxjs

Version:

Reactive Extensions for modern JavaScript

178 lines 5.13 kB
import { root } from '../util/root'; import { isObject } from '../util/isObject'; import { tryCatch } from '../util/tryCatch'; import { Observable } from '../Observable'; import { isFunction } from '../util/isFunction'; import { $$iterator } from '../symbol/iterator'; import { errorObject } from '../util/errorObject'; /** * We need this JSDoc comment for affecting ESDoc. * @extends {Ignored} * @hide true */ export class IteratorObservable extends Observable { constructor(iterator, project, thisArg, scheduler) { super(); if (iterator == null) { throw new Error('iterator cannot be null.'); } if (isObject(project)) { this.thisArg = project; this.scheduler = thisArg; } else if (isFunction(project)) { this.project = project; this.thisArg = thisArg; this.scheduler = scheduler; } else if (project != null) { throw new Error('When provided, `project` must be a function.'); } this.iterator = getIterator(iterator); } static create(iterator, project, thisArg, scheduler) { return new IteratorObservable(iterator, project, thisArg, scheduler); } static dispatch(state) { const { index, hasError, thisArg, project, iterator, subscriber } = state; if (hasError) { subscriber.error(state.error); return; } let result = iterator.next(); if (result.done) { subscriber.complete(); return; } if (project) { result = tryCatch(project).call(thisArg, result.value, index); if (result === errorObject) { state.error = errorObject.e; state.hasError = true; } else { subscriber.next(result); state.index = index + 1; } } else { subscriber.next(result.value); state.index = index + 1; } if (subscriber.isUnsubscribed) { return; } this.schedule(state); } _subscribe(subscriber) { let index = 0; const { iterator, project, thisArg, scheduler } = this; if (scheduler) { return scheduler.schedule(IteratorObservable.dispatch, 0, { index, thisArg, project, iterator, subscriber }); } else { do { let result = iterator.next(); if (result.done) { subscriber.complete(); break; } else if (project) { result = tryCatch(project).call(thisArg, result.value, index++); if (result === errorObject) { subscriber.error(errorObject.e); break; } subscriber.next(result); } else { subscriber.next(result.value); } if (subscriber.isUnsubscribed) { break; } } while (true); } } } class StringIterator { constructor(str, idx = 0, len = str.length) { this.str = str; this.idx = idx; this.len = len; } [$$iterator]() { return (this); } next() { return this.idx < this.len ? { done: false, value: this.str.charAt(this.idx++) } : { done: true, value: undefined }; } } class ArrayIterator { constructor(arr, idx = 0, len = toLength(arr)) { this.arr = arr; this.idx = idx; this.len = len; } [$$iterator]() { return this; } next() { return this.idx < this.len ? { done: false, value: this.arr[this.idx++] } : { done: true, value: undefined }; } } function getIterator(obj) { const i = obj[$$iterator]; if (!i && typeof obj === 'string') { return new StringIterator(obj); } if (!i && obj.length !== undefined) { return new ArrayIterator(obj); } if (!i) { throw new TypeError('Object is not iterable'); } return obj[$$iterator](); } const maxSafeInteger = Math.pow(2, 53) - 1; function toLength(o) { let len = +o.length; if (isNaN(len)) { return 0; } if (len === 0 || !numberIsFinite(len)) { return len; } len = sign(len) * Math.floor(Math.abs(len)); if (len <= 0) { return 0; } if (len > maxSafeInteger) { return maxSafeInteger; } return len; } function numberIsFinite(value) { return typeof value === 'number' && root.isFinite(value); } function sign(value) { let valueAsNumber = +value; if (valueAsNumber === 0) { return valueAsNumber; } if (isNaN(valueAsNumber)) { return valueAsNumber; } return valueAsNumber < 0 ? -1 : 1; } //# sourceMappingURL=IteratorObservable.js.map