Skip to content

Instantly share code, notes, and snippets.

@horodchukanton
Created September 17, 2016 13:19
Show Gist options
  • Save horodchukanton/9b15978e6a83fef755f4006f96d76b42 to your computer and use it in GitHub Desktop.
Save horodchukanton/9b15978e6a83fef755f4006f96d76b42 to your computer and use it in GitHub Desktop.
Simple JS event PubSub implementation
/**
Events, v2.0.0
Created by Anton Horodchuk for the ABillS Framework, http://abills.net.ua/
MIT License
Simple JavaScript Event PubSub implementation
One can install listener for event with 'on'
events.on('eventhappened', function(data){ console.log(data) });
events.emit('eventhappened', 'Hello, async world') // 'Hello, async world'
Sometimes you need to remove listeners in long time running application.
There are three separate interfaces for it.
1. Use returned object
var eventHandler = events.on('eventhappened', function(data){ console.log(data) });
// Do something here
eventHandler.remove();
2. Use named function and remove it explicitly
events.on('eventhappened', doSomeEventBasedAction);
// Later in your code
events.off('eventhappened', doSomeEventBasedAction);
3. Remove all listeners for event (Use with care)
events.off('eventhappened');
Also you can set one time callback (will remove itself after call)
events.once('specificevent', doSomeEventBasedAction);
*/
'use strict';
var Events = (function () {
var debug = 0;
var topics = {};
/**
* Set listener for event
* @param topic
* @param listener
* @returns {{remove: remove}}
*/
function on(topic, listener){
if (debug > 0) console.log('[ Events ] listen to :', topic);
topics[topic] = topics[topic] || [];
var index = topics[topic].push(listener) - 1;
// Return interface to remove self
return {
remove: function () {
delete topics[topic][index];
}
}
}
/**
* Set listener that will be removed after call
* @param topic
* @param listener
*/
function once(topic, listener){
if (debug > 0) console.log('[ Events ] once to :', topic);
on(topic, function (data) {
listener(data);
off(topic, listener);
});
}
/**
* Remove given listener for event or all if no listener specified
* @param topic
* @param listener
*/
function off(topic, listener){
if (topics[topic]) {
if (typeof listener === 'function') {
for (var i = 0; i < topics[topic].length; i++) {
if (topics[topic][i] === listener) {
topics[topic].splice(i, 1);
break;
}
}
}
else {
// Clear all listeners
topics[topic] = [];
}
}
}
/**
* Run all subscribed listeners
* @param topic
* @param data
*/
function emit(topic, data){
if (debug != 0) console.log('[ Events ] emmitted :', topic);
if (topics[topic]) {
topics[topic].forEach(function (fn) {
fn(data);
});
}
}
return {
on : on,
once : once,
off : off,
emit : emit,
debug: debug
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment