public
Last active

Simple Pub/Sub Implementation for jQuery

  • Download Gist
jquery-pubsub.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
/*
* 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);
 
*/
jquery-pubsub.min.js
JavaScript
1 2 3 4 5 6 7 8
/*
* 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);

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!

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.