pubsub.js vs jQuery events (v5)

Revision 5 of this benchmark created by op1ekun on


Description

pubsub.js tend to be the richest in functionality publish/subscribe JavaScript library.

pubsub.js library

Preparation HTML

<script src="https://ajax.googleapis.com/ajax/libs/yui/2.9.0/build/yuiloader/yuiloader-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://underscorejs.org/underscore.js"></script>
<script src="https://raw.github.com/Sahadar/pubsub.js/master/pubsub.js"></script>
<script src="https://raw.github.com/ajacksified/Mediator.js/master/lib/mediator.js"></script>
<script>
  var callback1 = function(event) {
    return false;
  };
  var callback2 = function() {};
  var payload = {
   somekey: 'some value'
  };
  var body;
  var someJqueryObject = $({});
  var mediator = new Mediator();


    var channels = {},
        obj = {};

    obj.subscribe = function (channel, subscriber, callback, context) {
        if (channel === undefined || callback === undefined || context === undefined) {
            throw new Error("Channel, callback, and context must be defined");
        }
        if (typeof channel !== "string") {
            throw new Error("Channel must be a string");
        }
        if (typeof subscriber !== "string") {
            throw new Error("Subscriber must be a string");
        }
        if (typeof callback !== "function") {
            throw new Error("Callback must be a function");
        }

        channels[channel] = (!channels[channel]) ? [] : channels[channel];
        channels[channel].push({
            subscriber: subscriber,
            callback: this.util.method(callback, context)
        });
    };

    obj.unsubscribe = function (subscriber) {
        $.each(channels, function (key, channel) {
            var foundObject = _.find(channel, function (item) {
                return item.subscriber === subscriber;
            });
            var index = _.indexOf(channel, foundObject);
            if (index !== -1) {
                delete channel[index];
                channel.splice(index, 1);
            }
        });
    };

    obj.publish = function (channel) {
        if (channel === undefined) {
            throw new Error("Channel must be defined");
        }
        if (typeof channel !== "string") {
            throw new Error("Channel must be a string");
        }
        var i, l, args = [].slice.call(arguments, 1);
        if (!channels[channel]) {
            return;
        }
        for (i = 0, l = channels[channel].length; i < l; i += 1) {
            channels[channel][i]['callback'].apply(this, args);
        }
    };


    obj.util = {
        method: function (fn, context) {
            return $.proxy(fn, context);
        }
    };

  var f = {
    subscribe: function (channel, callback, context) {
      pubsub.subscribe(channel, callback, context || this);
    },
    unsubscribe: function (subscriber) {
      pubsub.unsubscribe(subscriber);
    },
    publish: function (channel, args) {
      pubsub.publish(channel, [args]);
    }
  };

  var f2 = {
    subscribe: function (channel, subscriber, callback, context) {
      obj.subscribe(channel, subscriber, callback, context || this);
    },
    unsubscribe: function (subscriber) {
      obj.unsubscribe(subscriber);
    },
    publish: function (channel) {
      obj.publish.apply(obj, arguments);
    }
  };

  // let's use jQuery.ready to make sure that the DOM is ready,
  // before trying to work with it
  jQuery(function() {
   // we'll use the body element to exchange messages for jQuery
   // if using deeper nested elements, jQuery will be slower, as custom events bubble
   body = $('body');
  
   // subscribe our callback1 function to the custom event for jQuery, only once
   body.bind('my-event', callback1);
  
   // subscribe our callback1 function to the custom event for the plain jQuery object (non-DOM)
   someJqueryObject.bind('my-event', callback1);
  
   // subscribe our callback2 function to the message for PubSub
   pubsub.subscribe('my-event', callback2)
  
mediator.subscribe('my-event', callback2);
f.subscribe('my-event', callback2);
f2.subscribe('my-event', 'subscriber', callback2);


   // Use document instead of 'body' as the anchor for custom events
   doc = $(document)
  });
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
jQuery DOM - trigger
body.trigger('my-event', payload);
ready
jQuery Object - trigger
someJqueryObject.trigger('my-event', payload);
ready
pubsub.js - publish
pubsub.publish('my-event', [payload]);
ready
jQuery document - trigger
doc.trigger('my-event', payload);
ready
mediator.js - publish
mediator.publish('my-event', payload);
ready
f. publish
f.publish('my-events', payload);
ready
f2.publish
f2.publish('my-events', payload);
ready
YUI trigger
YUI().use('event-custom', function(Y) {
    Y.on('my-events', callback1);

    Y.fire('my-events', [payload]);
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.