Pub/Sub implementations (v13)

Revision 13 of this benchmark created by Michael on


Description

Added pubsub implementation using jQuery 1.7 $.Callbacks. Inspired by http://addyosmani.com/blog/jquery-1-7s-callbacks-feature-demystified/ .

Preparation HTML

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script>
  ;
  (function(d) {
  
    // the topic/subscription hash
    var cache = {};
  
    d.publish1 = function( /* String */ topic, /* Array? */ args) {
      cache[topic] && d.each(cache[topic], function() {
        this.apply(d, args || []);
      });
    };
  
    d.subscribe1 = function( /* String */ topic, /* Function */ callback) {
      if (!cache[topic]) {
        cache[topic] = [];
      }
      cache[topic].push(callback);
      return [topic, callback]; // Array
    };
  
    d.unsubscribe1 = function( /* Array */ handle) {
      var t = handle[0];
      cache[t] && d.each(cache[t], function(idx) {
        if (this == handle[1]) {
          cache[t].splice(idx, 1);
        }
      });
    };
  
  })(jQuery);
  
  /*!
   * jQuery Tiny Pub/Sub - v0.3pre - 11/4/2010
   * http://benalman.com/
   * 
   * Copyright (c) 2010 "Cowboy" Ben Alman
   * Dual licensed under the MIT and GPL licenses.
   * http://benalman.com/about/license/
   */
  /*!
   * jQuery Tiny Pub/Sub - v0.X - 11/18/2010
   * http://benalman.com/
   * 
   * Original Copyright (c) 2010 "Cowboy" Ben Alman
   * Dual licensed under the MIT and GPL licenses.
   * http://benalman.com/about/license/
   *
   * Made awesome by Rick Waldron
   *
   */
  (function(jQuery) {
    var o = jQuery({});
    jQuery.each({
      "subscribe2": "bind",
      "unsubscribe2": "unbind",
      "publish2": "trigger"
    }, function(fn, api) {
      jQuery[fn] = function() {
        o[api].apply(o, arguments);
      };
    });
  })(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.
    $.publish3 = 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
    $.subscribe3 = 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
    $.unsubscribe3 = 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);
  
  
    (function(d) {
    
      var cache = {};
    
      d.publish4 = function(topic, args) {
        if (cache[topic]) { 
          var currentCache = cache[topic],
              currentArgs = args || [];
              
          for (var i = 0, j = currentCache.length; i < j; i++) {
            currentCache[i].apply(d, currentArgs);
          }
        }
      };
    
      d.subscribe4 = function(topic,callback) {
        if (!cache[topic]) {
          cache[topic] = [];
        }
        cache[topic].push(callback);
        return [topic, callback]; 
      };
    
      d.unsubscribe4 = function(handle) {
        var topic = handle[0];
        if (cache[topic]) {
          var currentCache = cache[topic];
          for (var i = 0, j = currentCache.length; i < j; i++) {
            if (currentCache[i] === handle[1]) {
              currentCache.splice(i, 1);
            }        
          }
        }
      };
    
    })(jQuery);


/*
using jquery 1.7 $.Callback
*/

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

})(jQuery);




</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Object cache (Higgins)
var handle = $.subscribe1('foo', function() {
  1 + 1;
});

$.publish1('foo', ['bar']);

$.unsubscribe1(handle);
ready
jQuery events
$.subscribe2('foo', function() {
  1 + 1;
});

$.publish2('foo', ['bar']);

$.unsubscribe2('foo');
ready
higgins inspired
var handle = $.subscribe3('foo', function(msg) {
  1 + 1;
});

$.publish3('foo', ['bar']);

$.unsubscribe3(handle);
ready
higgins again
var handle = $.subscribe4('foo', function(msg) {
  1 + 1;
});

$.publish4('foo', ['bar']);

$.unsubscribe4(handle);
ready
jQuery $.Callbacks
var topic = $.Topic('foo'), fn = function(msg) { 1 + 1; };

topic.subscribe(fn);
topic.publish('bar');
topic.unsubscribe(fn);
ready

Revisions

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