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 | 1 1 1 1 1 20 1 20 20 1 20 1 1 20 20 1 20 20 20 1 31 31 31 31 1 30 30 11 30 1 11 11 11 6 1 14 14 14 12 14 14 3 1 3 1 50 50 8 8 1 7 42 1 | import {Operator} from '../Operator'; import {Observable} from '../Observable'; import {Subscriber} from '../Subscriber'; import {Subscription} from '../Subscription'; import {tryCatch} from '../util/tryCatch'; import {errorObject} from '../util/errorObject'; import {OuterSubscriber} from '../OuterSubscriber'; import {subscribeToResult} from '../util/subscribeToResult'; export function switchMap<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 SwitchMapOperator(project, resultSelector)); } class SwitchMapOperator<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 SwitchMapSubscriber(subscriber, this.project, this.resultSelector); } } class SwitchMapSubscriber<T, R, R2> extends OuterSubscriber<T, R> { private innerSubscription: Subscription<T>; private hasCompleted = 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 { const index = this.index++; const destination = this.destination; let result = tryCatch(this.project)(value, index); if (result === errorObject) { destination.error(result.e); } else { const innerSubscription = this.innerSubscription; if (innerSubscription) { innerSubscription.unsubscribe(); } this.add(this.innerSubscription = subscribeToResult(this, result, value, index)); } } _complete(): void { const innerSubscription = this.innerSubscription; this.hasCompleted = true; if (!innerSubscription || innerSubscription.isUnsubscribed) { this.destination.complete(); } } notifyComplete(innerSub: Subscription<R>): void { this.remove(innerSub); const prevSubscription = this.innerSubscription; if (prevSubscription) { prevSubscription.unsubscribe(); } this.innerSubscription = null; if (this.hasCompleted) { this.destination.complete(); } } notifyError(err: any): void { this.destination.error(err); } 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); } } } |