Skip to content

Instantly share code, notes, and snippets.

@mikehadlow
Created January 19, 2011 16:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mikehadlow/786386 to your computer and use it in GitHub Desktop.
Save mikehadlow/786386 to your computer and use it in GitHub Desktop.
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));
@mikehadlow
Copy link
Author

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