Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
A simple javascript event bus
var Suteki = Suteki || {};
Suteki.new_eventBus = (function(){
var self = {};
var subscriptions = {};
var unsubscribeTokens = [];
var subscriptionPointers = [];
self.subscribe = function(nameOfMessage, callback){
var i;
var subscriptionPointer;
var unsubscribeToken;
if(typeof nameOfMessage !== 'string'){
throw new Error("Suteki.eventBus.subscribe requires a first string argument 'nameOfMessage'");
}
if(typeof callback !== 'function'){
throw new Error("Suteki.eventBus.subscribe requires a second function argument 'callback'")
}
if(!subscriptions[nameOfMessage]){
subscriptions[nameOfMessage] = [];
}
subscriptions[nameOfMessage].push(callback);
// package and return an unsubscribe token.
subscriptionPointer = { nameOfMessage:nameOfMessage, callbackIndex: subscriptions[nameOfMessage].length-1 };
i = subscriptionPointers.length;
unsubscribeToken = {};
subscriptionPointers[i] = subscriptionPointer;
unsubscribeTokens[i] = unsubscribeToken;
return unsubscribeToken;
};
self.publish = function(nameOfMessage, data){
if(typeof nameOfMessage !== 'string'){
throw new Error("Suteki.eventBus.publish requires a first string argument 'nameOfMessage'");
}
if(!data){
throw new Error("Suteki.eventBus.publish requires a second argument 'data'");
}
var i;
var callback;
if(subscriptions[nameOfMessage]) {
for(i=0; i<subscriptions[nameOfMessage].length; i++){
callback = subscriptions[nameOfMessage][i];
if(callback){
callback(data);
}
}
}
};
self.unsubscribe = function(unsubscribeToken){
var subscriptionPointer = subscriptionPointers[unsubscribeTokens.indexOf(unsubscribeToken)];
subscriptions[subscriptionPointer.nameOfMessage][subscriptionPointer.callbackIndex] = null;
};
return self;
});
// for testing in node
if(exports) {
exports.new_eventBus = Suteki.new_eventBus;
}
// run tests in node
var Suteki = Suteki || {};
Suteki.eventBus = require('./Suteki.EventBus');
Suteki.eventBusTests = (function(new_bus){
if(!new_bus){
throw new Error("requires Suteki.EventBus.js");
}
var assert = function(passed, message){
if(!passed){
console.log("FAILED " + (message || ""))
};
};
var tests = {};
tests.should_be_able_to_publish_and_subscribe = function(){
var bus = new_bus();
var testMessage = "myTestMessage";
var handler1;
var handler2;
bus.subscribe(testMessage, function(data){
if(data === "Hello World"){
handler1 = "OK";
}
});
bus.subscribe(testMessage, function(data){
if(data === "Hello World"){
handler2 = "OK";
}
});
bus.publish(testMessage, "Hello World");
assert(handler1 === "OK", "Handler 1 Failed");
assert(handler2 === "OK", "Handler 2 Failed");
};
tests.should_be_able_to_subscribe_and_unsubscribe = function(){
var bus = new_bus();
var testMessage = "myTestMessage";
var resultData = "";
var unsubscribeToken = bus.subscribe(testMessage, function(data){
resultData = data;
});
bus.publish(testMessage, "Hello");
assert(resultData === "Hello", "subscription failed");
bus.unsubscribe(unsubscribeToken);
bus.publish(testMessage, "No!");
assert(resultData !== "No!", "unsubscribe failed, callback still present.");
};
(function(){
var testName;
for(testName in tests){
if(tests.hasOwnProperty(testName)){
console.log(">>> " + testName.replace(/_/g, " "));
tests[testName]();
}
}
}());
}(Suteki.eventBus.new_eventBus));
Owner

mikehadlow commented Jan 19, 2011

Run the test in node like this:
node Embassy.EventBusTests.js
should be able to publish and subscribe
should be able to subscribe and unsubscribe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment