Pub/Sub Javascript
Subscribe Once
by vtortola
HTML
<div id="container">
<div id="all-messages"><h3>All messages</h3></div>
<div id="blue-messages"></div>
<div id="red-messages"></div>
<div id="yellow-messages"></div>
</div>
CSS
#container > div{
font-family:Tahoma;
letter-spacing:1px;
border:none;
width:200px;
height:200px;
float:left;
padding:5px;
text-align:center;
font-size:9px;
margin:1px;
background-color:black;
color:white;
}
#red-messages{
background-color:red !important;
}
#blue-messages{
background-color:blue !important;
}
#yellow-messages{
background-color:gold !important;
}
hr{
clear:both;
visibility:hidden;
}
JavaScript
var messageDispatcher = function(){
var me ={};
var _handlers = [];
var _handlerIdCount = 0;
me.subscribe = function(predicate, handler){
var id =_handlerIdCount++;
_handlers.push({predicate:predicate, handle:handler, id:id});
return id;
};
me.subscribeOnce = function(predicate, handler, timeout, timeoutMessage){
var id =_handlerIdCount++;
console.log('tom ' + timeoutMessage);
var timer = setTimeout(function(){
me.unsubscribe(id);
if(timeoutMessage)
handler(timeoutMessage);
},timeout);
_handlers.push({
predicate:predicate,
handle:function(){
clearTimeout(timer);
me.unsubscribe(id);
handler.apply(me, arguments);
},
id:id
});
return id;
};
me.unsubscribe = function(subscriptionId){
var items = _handlers.filter(function(h){ return h.id === subscriptionId});
if(items && items.length){
var index = _handlers.indexOf(items[0]);
if (index > -1) {
_handlers.splice(index, 1);
}
}
};
me.push = function(message){
var handled = false;
_handlers.forEach(function(h){
if(h.predicate(message)){
handled=true;
h.handle(message);
}
});
if(!handled){
// todo: unhandled message
}
};
return me;
};
var md = messageDispatcher();
// Subscribe and subscribe once
md.subscribe(function(msg){ return msg && msg.all;}, // predicate
function(message){$('#all-messages').append('<div>'+JSON.stringify(message)+'</div>');});
md.subscribeOnce(function(msg){return msg && msg.all;},
function(message){...