Skip to content

Commit d8c835a

Browse files
committed
perf(first): remove tryCatch/errorObject for custom tryCatching, 970k ops -> 1.27M ops/sec
1 parent ec0199f commit d8c835a

File tree

1 file changed

+44
-25
lines changed

1 file changed

+44
-25
lines changed

src/operator/first.ts

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import {Observable} from '../Observable';
22
import {Operator} from '../Operator';
33
import {Subscriber} from '../Subscriber';
4-
import {tryCatch} from '../util/tryCatch';
5-
import {errorObject} from '../util/errorObject';
64
import {EmptyError} from '../util/EmptyError';
75

86
/**
@@ -41,34 +39,55 @@ class FirstSubscriber<T, R> extends Subscriber<T> {
4139
super(destination);
4240
}
4341

44-
protected _next(value: T): void {
45-
const { destination, predicate, resultSelector } = this;
42+
next(value: T): void {
4643
const index = this.index++;
47-
let passed: any = true;
48-
if (predicate) {
49-
passed = tryCatch(predicate)(value, index, this.source);
50-
if (passed === errorObject) {
51-
destination.error(errorObject.e);
52-
return;
53-
}
44+
if (this.predicate) {
45+
this._tryPredicate(value, index);
46+
} else {
47+
this._emit(value, index);
5448
}
55-
if (passed) {
56-
if (resultSelector) {
57-
let result = tryCatch(resultSelector)(value, index);
58-
if (result === errorObject) {
59-
destination.error(errorObject.e);
60-
return;
61-
}
62-
destination.next(result);
63-
} else {
64-
destination.next(value);
65-
}
66-
destination.complete();
67-
this.hasCompleted = true;
49+
}
50+
51+
private _tryPredicate(value: T, index: number) {
52+
let result: any;
53+
try {
54+
result = this.predicate(value, index, this.source);
55+
} catch (err) {
56+
this.destination.error(err);
57+
return;
58+
}
59+
if (result) {
60+
this._emit(value, index);
61+
}
62+
}
63+
64+
private _emit(value: any, index: number) {
65+
if (this.resultSelector) {
66+
this._tryResultSelector(value, index);
67+
return;
68+
}
69+
this._emitFinal(value);
70+
}
71+
72+
private _tryResultSelector(value: T, index: number) {
73+
let result: any;
74+
try {
75+
result = this.resultSelector(value, index);
76+
} catch (err) {
77+
this.destination.error(err);
78+
return;
6879
}
80+
this._emitFinal(result);
81+
}
82+
83+
private _emitFinal(value: any) {
84+
const destination = this.destination
85+
destination.next(value);
86+
destination.complete();
87+
this.hasCompleted = true;
6988
}
7089

71-
protected _complete(): void {
90+
complete(): void {
7291
const destination = this.destination;
7392
if (!this.hasCompleted && typeof this.defaultValue !== 'undefined') {
7493
destination.next(this.defaultValue);

0 commit comments

Comments
 (0)