Update: Since writing this post I’ve started using a modified version of Peter Higgens jQuery specific pub/sub solution. Here’s the updated version I’m using now, along with an App namespace:


App = {};
App.cache = {};
App.publish = function(topic, args){
    App.cache[topic] && $.each(App.cache[topic], function(){
        this.apply($, args || []);
    });
};
App.subscribe = function(topic, callback){
    if(!App.cache[topic]){
        App.cache[topic] = [];
    }
    App.cache[topic].push(callback);
    return [topic, callback];
};
App.unsubscribe = function(handle){
    var t = handle[0];
    App.cache[t] && $.each(App.cache[t], function(idx){
        if(this == handle[1]){
            App.cache[t].splice(idx, 1);
        }
    });
};

Over the past month or so the idea of Javascript Pubsub (Publish / Subscribe) has gotten a lot of publicity. Rebecca Murphey (of the YayQuery podcast / awesome JS dev) spoke at the jQuery Conference in Boston about it and more then a few example scripts have popped up for all sorts of different JS libraries (Dojo, jQuery etc.). If you don’t know what Pub/Sub is you should definitely check out Rebecca’s blog post and Ben Nadal’s post for more in depth detail.

6 months ago I started, what I was calling at the time, jHooks (Javascript Hooks). The code I built around the idea of “hooks” was, in practice, the exact same thing as Pub/Sub. I’ve ported the code to use the, Paul Irish endorsed, Pub/Sub naming conventions. Having to change the code’s object name was a struggle though. With “jHooks” it was very simple and straightforward to use that name as the object name and house all the methods subscriptions within it. I’ve reluctantly used the name “ps” until I find something better.

As the title of this post mentions, this version of pub/sub is library agnostic (and only 27 lines, un-compressed).

The Code

Download: http://darcyclarke.me/dev/pubsub/pubsub.js

    (function(window){
        ps = {},
        ps = window.ps,
        ps.subscriptions = [],
        ps.subscribe = function(name, callback){
            ps.subscriptions.push({"name": name, "callback": callback});
            return [name,callback];
        },
        ps.unsubscribe = function(args){
            for(x=0;x<ps.subscriptions.length;x++){
                if(ps.subscriptions[x].name == args[0], ps.subscriptions[x].callback == args[1])
                    ps.subscriptions.splice(x, 1);
            }
        },
        ps.publish = function(name, args){
            var temp = [];
            if(ps.subscriptions.length > 0){
                for(var x=0;x<ps.subscriptions.length;x++) {
                    if(ps.subscriptions[x].name == name)
                        temp.push({"fn":ps.subscriptions[x].callback});
                }
                for(x=0;x<temp.length;x++){
                    temp[x].fn.apply(this,[args]);
                }
            }
        };
    })(window);

Example Use

Set up a publish point with a string name and optional data to pass to the subscribed callback functions.

$("submit").bind("click", function(){
	ps.publish("login", {"username":$("#username").val(), "password":$("#password").val() });
});

Subscribe to a publish point using the same string as the identifier.

ps.subscribe("login", function(data){
	console.log("Login Info: " + data)
});

Unsubscribe by passing in the subscription

var login_function = ps.subscribe("login", function(data){
	console.log("Login Info: " + data)
});

$(".clear_login_subscription").bind("click", function(){
	ps.unsubscribe(login_function);
});

5 Comments

[...] read my blog before. I wrote library agnostic version of “PubSub” (Publish / Subscribe http://darcyclarke.me/development/library-agnostic-pubsub-publish-subscribe/) which we’ll be incorporating here in a second. I bring this up only to note that keeping [...]

Autoverzekering online Posted: Jan 28, 2011 @ 9:36pm

great article

Kit Melson Posted: Feb 13, 2011 @ 9:04pm

One of the more impressive blogs Ive seen. Thanks a lot for keeping the web classy for something new. Youve got style, class, bravado. I mean it. Please continue the good work because without the internet is definitely lacking in intelligence.

Flores Posted: Jan 28, 2012 @ 7:52pm

Hey Darcy, thanks for the code!. just what i need

Brad Posted: Oct 28, 2013 @ 2:57pm

I used this in 2011 in an object literal pattern and it was great. It seems the new method only uses $.each from jQuery which can easily be ported to a library agnostic, like the original version.

Rebecca’s blog is down…

Leave a Reply: