Skip to content

Commit

Permalink
perf: Don't clone observers unless you have to (#6842)
Browse files Browse the repository at this point in the history
  • Loading branch information
benlesh authored Feb 21, 2022
1 parent 64caf87 commit 3289d20
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/internal/Subject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { errorContext } from './util/errorContext';
*/
export class Subject<T> extends Observable<T> implements SubscriptionLike {
closed = false;

private currentObservers: Observer<T>[] | null = null;

/** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */
observers: Observer<T>[] = [];
/** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */
Expand Down Expand Up @@ -58,8 +61,10 @@ export class Subject<T> extends Observable<T> implements SubscriptionLike {
errorContext(() => {
this._throwIfClosed();
if (!this.isStopped) {
const copy = this.observers.slice();
for (const observer of copy) {
if (!this.currentObservers) {
this.currentObservers = Array.from(this.observers);
}
for (const observer of this.currentObservers) {
observer.next(value);
}
}
Expand Down Expand Up @@ -95,7 +100,7 @@ export class Subject<T> extends Observable<T> implements SubscriptionLike {

unsubscribe() {
this.isStopped = this.closed = true;
this.observers = null!;
this.observers = this.currentObservers = null!;
}

get observed() {
Expand All @@ -118,9 +123,15 @@ export class Subject<T> extends Observable<T> implements SubscriptionLike {
/** @internal */
protected _innerSubscribe(subscriber: Subscriber<any>) {
const { hasError, isStopped, observers } = this;
return hasError || isStopped
? EMPTY_SUBSCRIPTION
: (observers.push(subscriber), new Subscription(() => arrRemove(observers, subscriber)));
if (hasError || isStopped) {
return EMPTY_SUBSCRIPTION;
}
this.currentObservers = null;
observers.push(subscriber);
return new Subscription(() => {
this.currentObservers = null;
arrRemove(observers, subscriber);
});
}

/** @internal */
Expand Down

0 comments on commit 3289d20

Please sign in to comment.