Skip to content

Instantly share code, notes, and snippets.

@safe1981
Created March 13, 2012 04:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save safe1981/2026701 to your computer and use it in GitHub Desktop.
Save safe1981/2026701 to your computer and use it in GitHub Desktop.
Javascript: Pub/Sub Design pattern (Observer Pattern)
var PubSub = {}; //create empty object!
(function(p){
"use strict";
var topics = {},
lastUid = -1;
var publish = function( topic , data){
if ( !topics.hasOwnProperty( topic ) ){
return false;
}
var notify = function(){
var subscribers = topics[topic],
throwException = function(e){
return function(){
throw e;
};
};
for ( var i = 0, j = subscribers.length; i < j; i++ ){
try {
subscribers[i].func( topic, data );
} catch( e ){
setTimeout( throwException(e), 0);
}
}
};
setTimeout( notify , 0 ); //즉시 notify 메소드 실행
return true;
};
/**
* Publishes the topic, passing the data to it's subscribers
* @topic (String): The topic to publish
* @data: The data to pass to subscribers
**/
p.publish = function( topic, data ){
return publish( topic, data, false );
};
/**
* Subscribes the passed function to the passed topic.
* Every returned token is unique and should be stored if you need to unsubscribe
* @topic (String): The topic to subscribe to
* @func (Function): The function to call when a new topic is published
**/
p.subscribe = function( topic, func ){
// topic is not registered yet
if ( !topics.hasOwnProperty( topic ) ){
topics[topic] = [];
}
var token = (++lastUid).toString();
topics[topic].push( { token : token, func : func } );
// return token for unsubscribing
return token;
};
/**
* Unsubscribes a specific subscriber from a specific topic using the unique token
* @token (String): The token of the function to unsubscribe
**/
p.unsubscribe = function( token ){
for ( var m in topics ){
if ( topics.hasOwnProperty( m ) ){
for ( var i = 0, j = topics[m].length; i < j; i++ ){
if ( topics[m][i].token === token ){
topics[m].splice( i, 1 );
return token;
}
}
}
}
return false;
};
});
// a sample subscriber (or observer)
var testSubscriber = function( topics , data ){
console.log( topics + ": " + data );
};
// add the function to the list of subscribers to a particular topic
// maintain the token (subscription instance) to enable unsubscription later
var testSubscription = PubSub.subscribe( 'example1', testSubscriber );
// publish a topic or message asyncronously
PubSub.publish( 'example1', 'hello scriptjunkie!' );
PubSub.publish( 'example1', ['test','a','b','c'] );
PubSub.publish( 'example1', [{'color':'blue'},{'text':'hello'}] );
// unsubscribe from further topics
setTimeout(function(){
PubSub.unsubscribe( testSubscription );
}, 0);
// test that we've fully unsubscribed
PubSub.publish( 'example1', 'hello again!');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment