76 lines
1.9 KiB
JavaScript
76 lines
1.9 KiB
JavaScript
const _subscriptions = Symbol('subscriptions');
|
|
const _lastSubscriptionId = Symbol('lastSubscriptionId');
|
|
|
|
/**
|
|
* Class to implement publish/subscribe pattern
|
|
*
|
|
* @class
|
|
* @classdesc Pub/sub mechanism
|
|
*/
|
|
export default class PubSub {
|
|
constructor() {
|
|
this[_subscriptions] = {};
|
|
this[_lastSubscriptionId] = 0;
|
|
}
|
|
|
|
/**
|
|
* Subscribe to event
|
|
*
|
|
* @param {string} eventName Event name
|
|
* @param {Function} callback Callback function
|
|
* @returns {void}
|
|
*/
|
|
subscribe(eventName, callback) {
|
|
if (eventName === undefined) {
|
|
throw new Error('Event name is required');
|
|
}
|
|
|
|
if (typeof callback !== 'function') {
|
|
throw new Error('Callback must be a function');
|
|
}
|
|
|
|
if (!this[_subscriptions].hasOwnProperty(eventName)) {
|
|
this[_subscriptions][eventName] = {};
|
|
}
|
|
|
|
const subscriptionId = `sub${this[_lastSubscriptionId]++}`;
|
|
this[_subscriptions][eventName][subscriptionId] = callback;
|
|
}
|
|
|
|
/**
|
|
* Removes a subscription
|
|
*
|
|
* @param {string} eventName Event name
|
|
* @param {Function} [callback] Callback function
|
|
* @returns {void}
|
|
*/
|
|
unsubscribe(eventName, callback) {
|
|
const callbacks = this[_subscriptions][eventName] || {};
|
|
for (let subscriptionId in callbacks) {
|
|
if (!callback) {
|
|
delete callbacks[subscriptionId];
|
|
} else if (callbacks[subscriptionId] === callback) {
|
|
delete callbacks[subscriptionId];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Publish event to all subscriptions
|
|
*
|
|
* @param {String} eventName Event name
|
|
* @param {any} [payload] Data that will be published
|
|
* @returns {void}
|
|
*/
|
|
publish(eventName, ...payload) {
|
|
if (eventName === undefined) {
|
|
throw new Error('Event name is required');
|
|
}
|
|
|
|
const callbacks = this[_subscriptions][eventName] || {};
|
|
for (let subscriptionId in callbacks) {
|
|
callbacks[subscriptionId](...payload);
|
|
}
|
|
}
|
|
}
|