Skip to content

Instantly share code, notes, and snippets.

@liamross
Last active March 31, 2020 00:05
Show Gist options
  • Save liamross/79c50a20ab9700fcb2c13a1938dcd62d to your computer and use it in GitHub Desktop.
Save liamross/79c50a20ab9700fcb2c13a1938dcd62d to your computer and use it in GitHub Desktop.
Different patterns for listening/subscribing to events within a class
export type Subscriber = (event: YourEvent) => void;
/**
* When you have specific events and want to use a subscriber pattern.
*/
class WithEventSubscribers {
private _subscribers: Partial<{ [type in YourEventTypes]: Subscriber[] }>;
constructor() {
this._subscribers = {};
}
subscribe(type: YourEventTypes, subscriber: Subscriber) {
(this._subscribers[type] ?? (this._subscribers[type] = [])).push(subscriber);
return this._removeSubscriber(type, subscriber);
}
private _removeSubscriber(type: YourEventTypes, subscriber: Subscriber) {
return () => this._subscribers[type] = this._subscribers[type]?.filter(s => s !== subscriber);
}
}
// To use:
const subscriber = (e: YourEvent) => console.log(e);
const withSubscribers = new WithEventSubscribers();
const unsubscribe = withSubscribers.subscribe('some-event-type', subscriber);
// Later...
unsubscribe()
export type EventListener = (event: YourEvent) => void;
/**
* When you have specific events and want to use an event listener pattern.
*/
class WithEventListeners {
private _eventListeners: Partial<{ [type in YourEventTypes]: EventListener[] }>;
constructor() {
this._eventListeners = {};
}
addEventListener(type: YourEventTypes, listener: EventListener) {
(this._eventListeners[type] ?? (this._eventListeners[type] = [])).push(listener);
}
removeEventListener(type: YourEventTypes, listener: EventListener) {
this._eventListeners[type] = this._eventListeners[type]?.filter(l => l !== listener);
}
}
// To use:
const eventListener = (e: YourEvent) => console.log(e);
const withEventListeners = new WithEventListeners();
withEventListeners.addEventListener('some-event-type', eventListener);
// Later...
withEventListeners.removeEventListener('some-event-type', eventListener);
export type Subscriber = () => void;
/**
* When you don't have specific events, just one thing to subscribe to.
*/
class WithSimpleSubscribers {
private _subscribers: Subscriber[];
constructor() {
this._subscribers = [];
}
subscribe(subscriber: Subscriber) {
this._subscribers.push(subscriber);
return this._removeSubscriber(subscriber);
}
private _removeSubscriber(subscriber: Subscriber) {
return () => this._subscribers.filter(s => s !== subscriber);
}
}
// To use:
const subscriber = () => console.log('fired');
const withSubscribers = new WithSimpleSubscribers();
const unsubscribe = withSubscribers.subscribe(subscriber);
// Later...
unsubscribe()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment