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 | 1 1 1 1 1 17 1 17 17 1 17 1 1 17 17 17 1 17 17 17 1 30 22 22 22 22 1 21 21 1 9 9 4 1 45 45 10 10 1 9 35 1 2 1 13 13 2 1 | import {Operator} from '../Operator'; import {Observable} from '../Observable'; import {Subscriber} from '../Subscriber'; import {tryCatch} from '../util/tryCatch'; import {errorObject} from '../util/errorObject'; import {OuterSubscriber} from '../OuterSubscriber'; import {subscribeToResult} from '../util/subscribeToResult'; export function switchFirstMap<T, R, R2>(project: (value: T, index: number) => Observable<R>, resultSelector?: (outerValue: T, innerValue: R, outerIndex: number, innerIndex: number) => R2): Observable<R> { return this.lift(new SwitchFirstMapOperator(project, resultSelector)); } class SwitchFirstMapOperator<T, R, R2> implements Operator<T, R> { constructor(private project: (value: T, index: number) => Observable<R>, private resultSelector?: (outerValue: T, innerValue: R, outerIndex: number, innerIndex: number) => R2) { } call(subscriber: Subscriber<R>): Subscriber<T> { return new SwitchFirstMapSubscriber(subscriber, this.project, this.resultSelector); } } class SwitchFirstMapSubscriber<T, R, R2> extends OuterSubscriber<T, R> { private hasSubscription: boolean = false; private hasCompleted: boolean = false; private index: number = 0; constructor(destination: Subscriber<R>, private project: (value: T, index: number) => Observable<R>, private resultSelector?: (outerValue: T, innerValue: R, outerIndex: number, innerIndex: number) => R2) { super(destination); } _next(value: T): void { if (!this.hasSubscription) { const index = this.index++; const destination = this.destination; let result = tryCatch(this.project)(value, index); if (result === errorObject) { destination.error(result.e); } else { this.hasSubscription = true; this.add(subscribeToResult(this, result, value, index)); } } } _complete(): void { this.hasCompleted = true; if (!this.hasSubscription) { this.destination.complete(); } } notifyNext(outerValue: T, innerValue: R, outerIndex: number, innerIndex: number): void { const { resultSelector, destination } = this; if (resultSelector) { const result = tryCatch(resultSelector)(outerValue, innerValue, outerIndex, innerIndex); if (result === errorObject) { destination.error(errorObject.e); } else { destination.next(result); } } else { destination.next(innerValue); } } notifyError(err: any): void { this.destination.error(err); } notifyComplete(): void { this.hasSubscription = false; if (this.hasCompleted) { this.destination.complete(); } } } |