Skip to content

Instantly share code, notes, and snippets.

@huttj
Created June 16, 2015 19:50
Show Gist options
  • Save huttj/84139731089feb228d3b to your computer and use it in GitHub Desktop.
Save huttj/84139731089feb228d3b to your computer and use it in GitHub Desktop.
Publish-subscribe implementation with special features.
var PubSub = (function PubSub() {
var subscriptions = {};
var publications = {};
var index = 0;
function sub(event, callback) {
// If already subbed, return the id
var subId = getSubId(callback);
if (subId) return subId;
if (typeof callback !== 'function') throw "Callback not a function";
if (subscriptions[event]) {
subscriptions[event][index] = callback;
} else {
subscriptions[event] = {};
subscriptions[event][index] = callback;
}
index++; // Might break after 9007199254740992 iterations
return index - 1;
}
// Send data to all subscribers of an event
function pub(event, data) {
// If no data is passed, make it a null to indicate that it was called, nonetheless
publications[event] = data || null;
for (var key in subscriptions[event]) {
subscriptions[event][key](data);
}
}
// Subscribe to the event and get last publication (if available)
function then(event, callback) {
var subId = sub(event, callback);
// If it was previously called, but no data was passed
// the value will be null
if (typeof publications[event] !== 'undefined') callback(publications[event]);
return subId;
}
// Unsubscribe a function from an event
function unsub(subId) {
if (typeof subId === 'function') subId = getSubId(subId);
for (var eventKey in subscriptions) {
for (var subKey in subscriptions[eventKey]) {
if (subKey === subId) {
delete subscriptions[eventKey][subKey];
return true;
}
}
}
return false;
}
function unsubAll(subArray) {
subArray.forEach(unsub);
console.log(subscriptions);
}
// Get last publication (or next if no last exists) only
function once(event, func) {
var wrapper = function(data) {
func(data);
unsub(wrapper);
};
return then(event, wrapper);
}
// Get next publication only
function next(event, func) {
var wrapper = function(data) {
func(data);
unsub(wrapper);
};
return sub(event, wrapper);
}
// Look through the list and get the function
function getSubId(func) {
for (var eventKey in subscriptions) {
for (var subKey in subscriptions[eventKey]) {
if (subscriptions[eventKey][subKey] == func) {
return subKey;
}
}
}
return null;
}
return {
sub: sub,
once: once,
then: then,
next: next,
pub: pub,
unsub: unsub,
getSubId: getSubId,
unsubAll: unsubAll
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment