From d8c835af898b59869ee965733d97a4c21be8fa9e Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Tue, 26 Jan 2016 13:48:48 -0800 Subject: [PATCH] perf(first): remove tryCatch/errorObject for custom tryCatching, 970k ops -> 1.27M ops/sec --- src/operator/first.ts | 69 +++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/operator/first.ts b/src/operator/first.ts index d80036ddf7..0943d1a80e 100644 --- a/src/operator/first.ts +++ b/src/operator/first.ts @@ -1,8 +1,6 @@ import {Observable} from '../Observable'; import {Operator} from '../Operator'; import {Subscriber} from '../Subscriber'; -import {tryCatch} from '../util/tryCatch'; -import {errorObject} from '../util/errorObject'; import {EmptyError} from '../util/EmptyError'; /** @@ -41,34 +39,55 @@ class FirstSubscriber extends Subscriber { super(destination); } - protected _next(value: T): void { - const { destination, predicate, resultSelector } = this; + next(value: T): void { const index = this.index++; - let passed: any = true; - if (predicate) { - passed = tryCatch(predicate)(value, index, this.source); - if (passed === errorObject) { - destination.error(errorObject.e); - return; - } + if (this.predicate) { + this._tryPredicate(value, index); + } else { + this._emit(value, index); } - if (passed) { - if (resultSelector) { - let result = tryCatch(resultSelector)(value, index); - if (result === errorObject) { - destination.error(errorObject.e); - return; - } - destination.next(result); - } else { - destination.next(value); - } - destination.complete(); - this.hasCompleted = true; + } + + private _tryPredicate(value: T, index: number) { + let result: any; + try { + result = this.predicate(value, index, this.source); + } catch (err) { + this.destination.error(err); + return; + } + if (result) { + this._emit(value, index); + } + } + + private _emit(value: any, index: number) { + if (this.resultSelector) { + this._tryResultSelector(value, index); + return; + } + this._emitFinal(value); + } + + private _tryResultSelector(value: T, index: number) { + let result: any; + try { + result = this.resultSelector(value, index); + } catch (err) { + this.destination.error(err); + return; } + this._emitFinal(result); + } + + private _emitFinal(value: any) { + const destination = this.destination + destination.next(value); + destination.complete(); + this.hasCompleted = true; } - protected _complete(): void { + complete(): void { const destination = this.destination; if (!this.hasCompleted && typeof this.defaultValue !== 'undefined') { destination.next(this.defaultValue);