Pub/Sub in JavaScript This seems to work, but for some reason I'm not entirely sure about it. 

Can anyone point out any issues with this simple pub/sub library?
Thank you! 

(function (undefined) {
    window.mylib = $.extend(window.mylib, (function () {

        var subscriptionsBag = function() {
            var self = this;
            self.count = -1;
            self.handlers = {};

            var cancel = function(index) {
                var self = this;
                delete self.handlers[index];
            };

            self.add = function (fn) {
                if (typeof(fn) !== "function") {
                    throw new Error("function expected.");
                }

                var index = ++self.count;
                self.handlers[self.count] = fn;

                return {
                    cancel: cancel.bind(self, index)
                };
            };

            self.fire = function(obj) {
                for (var handlerKey in self.handlers) {
                    if (!self.handlers.hasOwnProperty(handlerKey)) {
                        continue;
                    }
                    var handler = self.handlers[handlerKey];
                    if (!handler) continue;
                    handler(obj);
                }
            };
        };

        var subscriptions = {
            "": {}
        };

        var publish = function(e, obj) {
            var evt = "@" + e;
            var subs = subscriptions[evt];
            if (!subs) return;

            subs.fire(obj);
        };

        var subscribeTo = function (e, fn) {
            var evt = "@" + e;
            var subs = subscriptions[evt] = (subscriptions[evt] || new subscriptionsBag());
            return subs.add(fn);
        };

        var events = {
            publish: publish,
            subscribeTo: subscribeTo
        };

        return {
            events: events
        };
    })());
})();
Member names

The code is confusing because it involves neither event dispatch nor event handling - therefore is nothing to do with events - yet there are member names evt and events, where : 


the evt vars are actually uids used as object keys
the events object contains references to methods.


The loose-coupled nature of Pub/Sub does indeed tempt you into believing that it involves events. But no, it does not (at least typically not, and certainly not here). Whereas a Pub and its corresponding Subs can be in completely diffferent parts of the code base, when a Pub fires it informs the subscribers synchronously, in the same event thread. 

Similarly, the subscriptions object is not well named. It receives objects which can themselves be subscribed to, not subscriptions directly. If anything was to be named "subscriptions" it would be SubscriptionsBag's self.handlers - each handler is effectively a subscription.

Leveraging jQuery.Callbacks

You are already using jQuery - great!

The jQuery documentation includes a really neat example under jQuery.Callbacks(), showing how Callbacks() instances can be exploited for Pub/Sub. 

If you were to adopt this approach, it would :


take all the pain out of having to write/test your own .add(), .cancel() and fire() methods
replace your SubscriptionsBag() with a Topic() constructor
replace your subscriptions repository with a topics repository
give you nice monads that will method-chain.


You need do little more than adopt jQuery's code and assign the Topic constructor to your chosen namespace in lieu of jQuery, and trap the topics repository in a closure (or otherwise avoid the global namespace).

(function (lib, topics) {
    lib.Topic = function Topic (id) {
        var callbacks,
            topic = id &amp;&amp; topics[id];
        if (!topic) {
            callbacks = jQuery.Callbacks();
            topic = {
                publish: callbacks.fire,
                subscribe: callbacks.add,
                unsubscribe: callbacks.remove
            };
            if (id) {
                topics[id] = topic;
            }
        }
        return topic;
    };
})(window.mylib, {});


Thus, your versions of the usage examples in the jQuery documentation would be :

// Subscribers
window.mylib.Topic( "mailArrived" ).subscribe( fn1 );
window.mylib.Topic( "mailArrived" ).subscribe( fn2 );
window.mylib.Topic( "mailSent" ).subscribe( fn1 );

// Publishers
window.mylib.Topic( "mailArrived" ).publish( "hello world!" );
window.mylib.Topic( "mailSent" ).publish( "woo! mail!" );


And an example involving asynchronously derived data :

// Subscriber
var mailArrivedTopic = window.mylib.Topic("mailArrived").subscribe(fn1); // Note how the subscribe() method returns the Topic instance (monadic behaviour).

// Publisher
$.ajax({...}).then(mailArrivedTopic.publish);