Skip to content

Instantly share code, notes, and snippets.

@mindon
Last active August 29, 2015 14:07
Show Gist options
  • Save mindon/e5c6b3357eea18a4a2cb to your computer and use it in GitHub Desktop.
Save mindon/e5c6b3357eea18a4a2cb to your computer and use it in GitHub Desktop.
A simple JavaScript Sub/Pub
/* ----------- simple sub/pub --------------
* -- Author: Mindon Feng http://mindon.github.com
* -- Usage:
* BuPS.subscribe("event-string", function(data, cmd){});
* BuPS.publish("event-string", data);
*/
var BuPS={}, _DEBUG=false;
;(function(){
var cmds = {};
function debug() {
var cl = !!window.console;
if(cl && console.debug)
console.debug.apply(console, arguments);
else if(cl && console.log)
console.log.apply(console, arguments);
else
alert(Array.prototype.slice.apply(arguments).join(" "));
}
function clone(obj) { // copy data
if (!obj || "object" != typeof obj) return obj;
if (obj instanceof Number) {
return 0 + obj
} else if (obj instanceof Boolean) {
return obj == false ? false: true;
} else if (obj instanceof String) {
return obj.toString();
} else if (obj instanceof Array) {
var copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = (!obj[i] || "object" != typeof obj[i]) ? obj[i] : clone(obj[i]);
}
return copy;
} else if (obj instanceof Date) {
return new Date(obj.getTime());
} else if (obj instanceof Object) {
var copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) {
copy[attr] = (!obj[attr] || "object" != typeof obj[attr]) ? obj[attr] : clone(obj[attr]);
}
}
return copy;
}
}
function subscribe(cmd, fn) {
if(typeof fn != "function") {
_DEBUG && debug("[SUBSCRIBE] WARNING:", cmd, typeof fn, subscribe.caller.caller);
return false;
}
if(cmd.indexOf(',')>0) {
var c = cmd.split(/\s*,\s*/);
for(var i=0; i<c.length; i++){
c[i] && subscribe(c[i], fn);
}
return c.length;
}
if(!cmds[cmd]) {
cmds[cmd] = [fn];
} else {
var i = cmds[cmd].indexOf(fn);
if(i < 0) { // insert
cmds[cmd].push(fn);
} else { // update
_DEBUG && debug("[SUBSCRIBE] REPLACED:", cmd, i);
cmds[cmd][i] = fn;
}
}
var checkRxp = new RegExp("publish\\(\\s*[\'\"]" + cmd.replace(/\./g, "\\.") + "[\'\"],");
if(checkRxp.test(fn.toString())) {
debug &&debug("[SUBSCRIBE] FATAL: Suspicion loop calling publish & subscribe! // " + cmd);
}
}
function publish(cmd, data) {
var d = cmds[cmd];
if(!d || d.length == 0){
_DEBUG && debug("[PUBLISH] EMPTY:" + cmd);
return false;
}
var ok = 0;
_DEBUG && debug("[PUBLISH] "+cmd+": listener count = " +d.length);
for(var k=0, kmax=d.length; k<kmax; k++) {
try {
if(d[k] && typeof d[k] == "function") {
(d[k])(clone(data), cmd); // sync
ok++;
} else {
_DEBUG && debug("[PUBLISH] ERROR:", typeof d[k]);
}
} catch(e) {
_DEBUG && debug("[PUBLISH] FAILED:", "cmd:" +cmd, ", error: " +e.message, ", func: " +d[k]);
}
}
_DEBUG && debug("[PUBLISH] RESULT:", cmd +" = ", ok + "/" + d.length);
// remove undefined fn
var k = d.length -1;
while(k > 0) {
if(d[k] == undefined) {
d.splice(k, 1);
}
k -= 1;
}
}
function unsubscribe(fn) {
for(var k in cmds) {
var i = cmds[k].indexOf(fn);
if(i > -1) {
cmds[k][i] = undefined;
}
}
}
// export api
BuPS.subscribe = subscribe;
BuPS.publish = publish;
BuPS.unsubscribe = unsubscribe;
//bups.clone = clone;
//simple pubsub
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment