Skip to content

Commit 3289d20

Browse files
authoredFeb 21, 2022
perf: Don't clone observers unless you have to (#6842)
1 parent 64caf87 commit 3289d20

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed
 

‎src/internal/Subject.ts

+17-6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import { errorContext } from './util/errorContext';
1616
*/
1717
export class Subject<T> extends Observable<T> implements SubscriptionLike {
1818
closed = false;
19+
20+
private currentObservers: Observer<T>[] | null = null;
21+
1922
/** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */
2023
observers: Observer<T>[] = [];
2124
/** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */
@@ -58,8 +61,10 @@ export class Subject<T> extends Observable<T> implements SubscriptionLike {
5861
errorContext(() => {
5962
this._throwIfClosed();
6063
if (!this.isStopped) {
61-
const copy = this.observers.slice();
62-
for (const observer of copy) {
64+
if (!this.currentObservers) {
65+
this.currentObservers = Array.from(this.observers);
66+
}
67+
for (const observer of this.currentObservers) {
6368
observer.next(value);
6469
}
6570
}
@@ -95,7 +100,7 @@ export class Subject<T> extends Observable<T> implements SubscriptionLike {
95100

96101
unsubscribe() {
97102
this.isStopped = this.closed = true;
98-
this.observers = null!;
103+
this.observers = this.currentObservers = null!;
99104
}
100105

101106
get observed() {
@@ -118,9 +123,15 @@ export class Subject<T> extends Observable<T> implements SubscriptionLike {
118123
/** @internal */
119124
protected _innerSubscribe(subscriber: Subscriber<any>) {
120125
const { hasError, isStopped, observers } = this;
121-
return hasError || isStopped
122-
? EMPTY_SUBSCRIPTION
123-
: (observers.push(subscriber), new Subscription(() => arrRemove(observers, subscriber)));
126+
if (hasError || isStopped) {
127+
return EMPTY_SUBSCRIPTION;
128+
}
129+
this.currentObservers = null;
130+
observers.push(subscriber);
131+
return new Subscription(() => {
132+
this.currentObservers = null;
133+
arrRemove(observers, subscriber);
134+
});
124135
}
125136

126137
/** @internal */

0 commit comments

Comments
 (0)
Please sign in to comment.