Created
June 16, 2015 19:50
-
-
Save huttj/84139731089feb228d3b to your computer and use it in GitHub Desktop.
Publish-subscribe implementation with special features.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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