Skip to content

Instantly share code, notes, and snippets.

Created December 24, 2012 12:33
Show Gist options
  • Save anonymous/4369106 to your computer and use it in GitHub Desktop.
Save anonymous/4369106 to your computer and use it in GitHub Desktop.
JavaScript pubsub with Observer addon, the observer is also has fake array capability
function ObserverPubSub(parent, key_of_myself) {
this._topics = {};
this.length = 0;
this._subUid = -1;
this._parent = parent;
this._name = key_of_myself;
}
ObserverPubSub.prototype = {
//pubsub
on: function(topic, func, token) {
var topics = this._topics;
if (!topics[topic]) {
topics[topic] = [];
}
if (arguments.length == 2) token = (++this._subUid).toString();
topics[topic].push({
token: token,
func: func
});
return token;
},
emit: function(topic) {
var topics = this._topics,
args = arguments;
if (!topics[topic]) {
return false;
}
setTimeout(function() {
var subscribers = topics[topic],
len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func.apply(this, args);
}
}, 0);
return true;
},
unsub: function(token) {
var topics = this._topics;
for (var m in topics) {
if (topics[m]) {
for (var i = 0, j = topics[m].length; i < j; i++) {
if (topics[m][i].token === token) {
topics[m].splice(i, 1);
if (topics[m].length == 0) delete topics[m];
return token;
}
}
}
}
return false;
},
//observer
emit_recursive: function() {
this.emit.apply(this, arguments)
if (this._parent) this._parent.emit.apply(this._parent, arguments)
},
add: function(k, v) {
var objv = new ObserverPubSub(this, k);
this[k] = objv;
objv._set(v);
this.emit('add', k, v);
if (this._parent) this._parent.emit_recursive('childadd', this, this._name);
return k;
},
push: function(v) {
var k = this.length++;
this.add(k, v);
this.emit('length', this.length);
return k;
},
_set: function(k, v) {
var isnew = this[k] === undefined;
if (arguments.length == 1) {
v = k;
k = '_value';
}
if (this[k] instanceof ObserverPubSub) return this[k].set(v);
this[k] = v;
this.emit('set', k, v);
if (this._parent) this._parent.emit_recursive('childset', this, this._name);
return isnew;
},
set: function(k, v) {
if (!this._set.apply(this, arguments)) {
this.emit('change', k, v);
if (this._parent) this._parent.emit_recursive('childchange', this, this._name);
}
},
get: function(k) {
if (arguments.length == 0) return this['_value'];
return this[k];
},
toArray: function() {
var arr=[];
for (var i = 0, j = this.length; i < j; i++) {
arr[i]=this[i];
}
return arr;
}
};
//var arr= new ObserverPubSub();
//pubsub:
//var token=arr.on('foo',function(){})//token='0'
//arr._topics
//arr.unsub('0')
//arr.on('set',function(eventname,key,value){console.log(eventname,key,value)})
//arr.on('add',function(eventname,key,value){console.log(eventname,key,value)})
//arr.on('change',function(eventname,key,value){console.log(eventname,key,value)})
//arr.on('length',function(eventname,key,value){console.log(eventname,key,value)})
//arr.on('childset',function(eventname,key,value){console.log(eventname,key,value)})
//arr.on('childadd',function(eventname,key,value){console.log(eventname,key,value)})
//arr.on('childchange',function(eventname,key,value){console.log(eventname,key,value)})
//observer:
//arr.add('key',"value");
//arr.set('key',"value");
//arr.push("value");//add with key=length,length++
//arr.get('key');
//arr.get(); // key='_value'
//arr.set("value"); // key='_value'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment