Skip to content

Instantly share code, notes, and snippets.

@bentruyman
Created February 14, 2011 23:16
  • Star 23 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save bentruyman/826794 to your computer and use it in GitHub Desktop.
Simple Pub/Sub Implementation for jQuery
/*
* Simple Pub/Sub Implementation for jQuery
*
* Inspired by work from Peter Higgins (https://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js)
*
* This is about the simplest way to write a pubsub JavaScript implementation for use with jQuery.
*/
(function( $ ) {
// Cache of all topics
var topics = {};
// Iterates through all subscribers of a topic and invokes their callback,
// passing optional arguments.
$.publish = function( topic, args ) {
if ( topics[ topic ] ) {
var thisTopic = topics[ topic ],
thisArgs = args || [];
for ( var i = 0, j = thisTopic.length; i < j; i++ ) {
thisTopic[i].apply( $, thisArgs );
}
}
};
// Returns a handle needed for unsubscribing
$.subscribe = function( topic, callback ) {
if ( !topics[ topic ] ) {
topics[ topic ] = [];
}
topics[ topic ].push( callback );
return {
topic: topic,
callback: callback
};
};
// Removes the subscriber from the particular topic its handle was assigned to
$.unsubscribe = function( handle ) {
var topic = handle.topic;
if ( topics[ topic ] ) {
var thisTopic = topics[ topic ];
for ( var i = 0, j = thisTopic.length; i < j; i++ ) {
if ( thisTopic[i] === handle.callback ) {
thisTopic.splice( i, 1 );
// break; here? duplicate handles are possible
}
}
}
};
})( jQuery );
/*
For example:
var handle = $.subscribe('notification', function (msg) {
alert(msg);
});
$.publish('notification', ['Hello World']);
$.unsubscribe(handle);
*/
/*
* Simple Pub/Sub Implementation for jQuery
*
* Inspired by work from Peter Higgins (https://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js)
*
* This is about the simplest way to write a pubsub JavaScript implementation for use with jQuery.
*/
(function(a){var b={};a.publish=function(c,d){if(b[c]){var e=b[c],f=d||[];for(var g=0,h=e.length;g<h;g++)e[g].apply(a,f)}},a.subscribe=function(a,c){b[a]||(b[a]=[]),b[a].push(c);return{topic:a,callback:c}},a.unsubscribe=function(a){var c=a.topic;if(b[c]){var d=b[c];for(var e=0,f=d.length;e<f;e++)d[e]===a.callback&&d.splice(e,1)}}})(jQuery);
@bentruyman
Copy link
Author

In response to @gf3's comment:

Would on/fire cause confusion for users (being right alongside bind/trigger) as apposed to publish/subscribe?

Namespacing would be nice, but I think it would have to work a bit differently than jQuery's current event namespacing. jQuery event namespaces usually take the form of click.widget whereas most pubsub topics are written like paths /widget/click. I could see where a user might want to subscribe to all topics of a particular widget like $.subscribe('/myapp/status/*', callback);. So callback would be invoked for both /myapp/status/foo and /myapp/status/bar. However, if wildcards are introduced, I think the callback would need some sort of context as to what actual topic triggered it (foo or bar). Maybe pass it as the first arg? Or make it this in callback?

That's not to say we'd have to stick with this pattern of "paths as topics".

I could be over-thinking the namespacing a bit... :-| NO U!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment