1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 1 1 1 11 11 11 1 11 11 11 1 11 1 1 11 1 11 11 11 11 11 11 5 5 5 5 6 6 1 56 56 56 68 1 4 4 1 5 5 5 5 1 37 37 37 1 25 25 25 1 1 10 10 10 10 10 10 10 1 16 16 16 16 16 16 1 15 | import {Operator} from '../Operator'; import {Subscriber} from '../Subscriber'; import {Observable} from '../Observable'; import {Scheduler} from '../Scheduler'; import {Action} from '../scheduler/Action'; import {asap} from '../scheduler/asap'; /** * buffers values from the source for a specific time period. Optionally allows new buffers to be set up at an interval. * @param {number} the amount of time to fill each buffer for before emitting them and clearing them. * @param {number} [bufferCreationInterval] the interval at which to start new buffers. * @param {Scheduler} [scheduler] (optional, defaults to `asap` scheduler) The scheduler on which to schedule the * intervals that determine buffer boundaries. * @returns {Observable<T[]>} an observable of arrays of buffered values. */ export function bufferTime<T>(bufferTimeSpan: number, IbufferCreationInterval: number = null, Ischeduler: Scheduler = asap): Observable<T[]> { return this.lift(new BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, scheduler)); } class BufferTimeOperator<T, R> implements Operator<T, R> { constructor(private bufferTimeSpan: number, private bufferCreationInterval: number, private scheduler: Scheduler) { } call(subscriber: Subscriber<T>): Subscriber<T> { return new BufferTimeSubscriber( subscriber, this.bufferTimeSpan, this.bufferCreationInterval, this.scheduler ); } } class BufferTimeSubscriber<T> extends Subscriber<T> { private buffers: Array<T[]> = []; constructor(destination: Subscriber<T>, private bufferTimeSpan: number, private bufferCreationInterval: number, private scheduler: Scheduler) { super(destination); const buffer = this.openBuffer(); if (bufferCreationInterval !== null && bufferCreationInterval >= 0) { const closeState = { subscriber: this, buffer }; const creationState = { bufferTimeSpan, bufferCreationInterval, subscriber: this, scheduler }; this.add(scheduler.schedule(dispatchBufferClose, bufferTimeSpan, closeState)); this.add(scheduler.schedule(dispatchBufferCreation, bufferCreationInterval, creationState)); } else { const timeSpanOnlyState = { subscriber: this, buffer, bufferTimeSpan }; this.add(scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); } } _next(value: T) { const buffers = this.buffers; const len = buffers.length; for (let i = 0; i < len; i++) { buffers[i].push(value); } } _error(err) { this.buffers.length = 0; this.destination.error(err); } _complete() { const buffers = this.buffers; while (buffers.length > 0) { this.destination.next(buffers.shift()); } this.destination.complete(); } openBuffer(): T[] { let buffer = []; this.buffers.push(buffer); return buffer; } closeBuffer(buffer: T[]) { this.destination.next(buffer); const buffers = this.buffers; buffers.splice(buffers.indexOf(buffer), 1); } } function dispatchBufferTimeSpanOnly(state) { const subscriber: BufferTimeSubscriber<any> = state.subscriber; const prevBuffer = state.buffer; Eif (prevBuffer) { subscriber.closeBuffer(prevBuffer); } state.buffer = subscriber.openBuffer(); Eif (!subscriber.isUnsubscribed) { (<any>this).schedule(state, state.bufferTimeSpan); } } function dispatchBufferCreation(state) { const { bufferCreationInterval, bufferTimeSpan, subscriber, scheduler } = state; const buffer = subscriber.openBuffer(); const action = <Action>this; Eif (!subscriber.isUnsubscribed) { action.add(scheduler.schedule(dispatchBufferClose, bufferTimeSpan, { subscriber, buffer })); action.schedule(state, bufferCreationInterval); } } function dispatchBufferClose({ subscriber, buffer }) { subscriber.closeBuffer(buffer); } |