| import { fromArray } from './fromArray'; |
| import { isArray } from '../util/isArray'; |
| import { Subscriber } from '../Subscriber'; |
| import { OuterSubscriber } from '../OuterSubscriber'; |
| import { subscribeToResult } from '../util/subscribeToResult'; |
| import { iterator as Symbol_iterator } from '../../internal/symbol/iterator'; |
| export function zip(...observables) { |
| const resultSelector = observables[observables.length - 1]; |
| if (typeof resultSelector === 'function') { |
| observables.pop(); |
| } |
| return fromArray(observables, undefined).lift(new ZipOperator(resultSelector)); |
| } |
| export class ZipOperator { |
| constructor(resultSelector) { |
| this.resultSelector = resultSelector; |
| } |
| call(subscriber, source) { |
| return source.subscribe(new ZipSubscriber(subscriber, this.resultSelector)); |
| } |
| } |
| export class ZipSubscriber extends Subscriber { |
| constructor(destination, resultSelector, values = Object.create(null)) { |
| super(destination); |
| this.iterators = []; |
| this.active = 0; |
| this.resultSelector = (typeof resultSelector === 'function') ? resultSelector : null; |
| this.values = values; |
| } |
| _next(value) { |
| const iterators = this.iterators; |
| if (isArray(value)) { |
| iterators.push(new StaticArrayIterator(value)); |
| } |
| else if (typeof value[Symbol_iterator] === 'function') { |
| iterators.push(new StaticIterator(value[Symbol_iterator]())); |
| } |
| else { |
| iterators.push(new ZipBufferIterator(this.destination, this, value)); |
| } |
| } |
| _complete() { |
| const iterators = this.iterators; |
| const len = iterators.length; |
| this.unsubscribe(); |
| if (len === 0) { |
| this.destination.complete(); |
| return; |
| } |
| this.active = len; |
| for (let i = 0; i < len; i++) { |
| let iterator = iterators[i]; |
| if (iterator.stillUnsubscribed) { |
| const destination = this.destination; |
| destination.add(iterator.subscribe(iterator, i)); |
| } |
| else { |
| this.active--; |
| } |
| } |
| } |
| notifyInactive() { |
| this.active--; |
| if (this.active === 0) { |
| this.destination.complete(); |
| } |
| } |
| checkIterators() { |
| const iterators = this.iterators; |
| const len = iterators.length; |
| const destination = this.destination; |
| for (let i = 0; i < len; i++) { |
| let iterator = iterators[i]; |
| if (typeof iterator.hasValue === 'function' && !iterator.hasValue()) { |
| return; |
| } |
| } |
| let shouldComplete = false; |
| const args = []; |
| for (let i = 0; i < len; i++) { |
| let iterator = iterators[i]; |
| let result = iterator.next(); |
| if (iterator.hasCompleted()) { |
| shouldComplete = true; |
| } |
| if (result.done) { |
| destination.complete(); |
| return; |
| } |
| args.push(result.value); |
| } |
| if (this.resultSelector) { |
| this._tryresultSelector(args); |
| } |
| else { |
| destination.next(args); |
| } |
| if (shouldComplete) { |
| destination.complete(); |
| } |
| } |
| _tryresultSelector(args) { |
| let result; |
| try { |
| result = this.resultSelector.apply(this, args); |
| } |
| catch (err) { |
| this.destination.error(err); |
| return; |
| } |
| this.destination.next(result); |
| } |
| } |
| class StaticIterator { |
| constructor(iterator) { |
| this.iterator = iterator; |
| this.nextResult = iterator.next(); |
| } |
| hasValue() { |
| return true; |
| } |
| next() { |
| const result = this.nextResult; |
| this.nextResult = this.iterator.next(); |
| return result; |
| } |
| hasCompleted() { |
| const nextResult = this.nextResult; |
| return nextResult && nextResult.done; |
| } |
| } |
| class StaticArrayIterator { |
| constructor(array) { |
| this.array = array; |
| this.index = 0; |
| this.length = 0; |
| this.length = array.length; |
| } |
| [Symbol_iterator]() { |
| return this; |
| } |
| next(value) { |
| const i = this.index++; |
| const array = this.array; |
| return i < this.length ? { value: array[i], done: false } : { value: null, done: true }; |
| } |
| hasValue() { |
| return this.array.length > this.index; |
| } |
| hasCompleted() { |
| return this.array.length === this.index; |
| } |
| } |
| class ZipBufferIterator extends OuterSubscriber { |
| constructor(destination, parent, observable) { |
| super(destination); |
| this.parent = parent; |
| this.observable = observable; |
| this.stillUnsubscribed = true; |
| this.buffer = []; |
| this.isComplete = false; |
| } |
| [Symbol_iterator]() { |
| return this; |
| } |
| next() { |
| const buffer = this.buffer; |
| if (buffer.length === 0 && this.isComplete) { |
| return { value: null, done: true }; |
| } |
| else { |
| return { value: buffer.shift(), done: false }; |
| } |
| } |
| hasValue() { |
| return this.buffer.length > 0; |
| } |
| hasCompleted() { |
| return this.buffer.length === 0 && this.isComplete; |
| } |
| notifyComplete() { |
| if (this.buffer.length > 0) { |
| this.isComplete = true; |
| this.parent.notifyInactive(); |
| } |
| else { |
| this.destination.complete(); |
| } |
| } |
| notifyNext(outerValue, innerValue, outerIndex, innerIndex, innerSub) { |
| this.buffer.push(innerValue); |
| this.parent.checkIterators(); |
| } |
| subscribe(value, index) { |
| return subscribeToResult(this, this.observable, this, index); |
| } |
| } |
| //# sourceMappingURL=zip.js.map |