Home Manual Reference Source Test Repository

es6/operator/mergeAll.js

import { OuterSubscriber } from '../OuterSubscriber';
import { subscribeToResult } from '../util/subscribeToResult';
/**
 * 将高阶 Observable 转换成一阶 Observable ,一阶 Observable 会同时发出在内部
 * Observables 上发出的所有值。
 *
 * <span class="informal">打平高阶 Observable 。</span>
 *
 * <img src="./img/mergeAll.png" width="100%">
 *
 * `mergeAll` 订阅发出 Observables 的 Observalbe ,也称为高阶 Observable 。
 * 每当观察到发出的内部 Observable 时,它会订阅并发出输出 Observable 上的这个
 * 内部 Observable 的所有值。所有的内部 Observable 都完成了,输出 Observable
 * 才能完成。任何由内部 Observable 发出的错误都会立即在输出 Observalbe 上发出。
 *
 * @example <caption>为每个点击事件创建一个新的 interval Observable ,并将其输出混合为一个 Observable</caption>
 * var clicks = Rx.Observable.fromEvent(document, 'click');
 * var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000));
 * var firstOrder = higherOrder.mergeAll();
 * firstOrder.subscribe(x => console.log(x));
 *
 * @example <caption>每次点击都会从0到9计数(每秒计数一次),但只允许最多同时只能有两个计时器</caption>
 * var clicks = Rx.Observable.fromEvent(document, 'click');
 * var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000).take(10));
 * var firstOrder = higherOrder.mergeAll(2);
 * firstOrder.subscribe(x => console.log(x));
 *
 * @see {@link combineAll}
 * @see {@link concatAll}
 * @see {@link exhaust}
 * @see {@link merge}
 * @see {@link mergeMap}
 * @see {@link mergeMapTo}
 * @see {@link mergeScan}
 * @see {@link switch}
 * @see {@link zipAll}
 *
 * @param {number} [concurrent=Number.POSITIVE_INFINITY] 可以同时订阅的输入
 * Observables 的最大数量。
 * @return {Observable} 该 Observable 发出的值来自所有由源 Observable 发出的
 * 内部 Observables 。
 * @method mergeAll
 * @owner Observable
 */
export function mergeAll(concurrent = Number.POSITIVE_INFINITY) {
    return this.lift(new MergeAllOperator(concurrent));
}
export class MergeAllOperator {
    constructor(concurrent) {
        this.concurrent = concurrent;
    }
    call(observer, source) {
        return source.subscribe(new MergeAllSubscriber(observer, this.concurrent));
    }
}
/**
 * We need this JSDoc comment for affecting ESDoc.
 * @ignore
 * @extends {Ignored}
 */
export class MergeAllSubscriber extends OuterSubscriber {
    constructor(destination, concurrent) {
        super(destination);
        this.concurrent = concurrent;
        this.hasCompleted = false;
        this.buffer = [];
        this.active = 0;
    }
    _next(observable) {
        if (this.active < this.concurrent) {
            this.active++;
            this.add(subscribeToResult(this, observable));
        }
        else {
            this.buffer.push(observable);
        }
    }
    _complete() {
        this.hasCompleted = true;
        if (this.active === 0 && this.buffer.length === 0) {
            this.destination.complete();
        }
    }
    notifyComplete(innerSub) {
        const buffer = this.buffer;
        this.remove(innerSub);
        this.active--;
        if (buffer.length > 0) {
            this._next(buffer.shift());
        }
        else if (this.active === 0 && this.hasCompleted) {
            this.destination.complete();
        }
    }
}
//# sourceMappingURL=mergeAll.js.map