最高のパフォーマンスのJavascriptは購読システム(pub/sub)Abiter.jsソース分析を発表しました.

16561 ワード

var Arbiter = (function () {

 var create_arbiter = function () {

  var subscriptions = {};//    

  var wildcard_subscriptions = {};//        

  var persistent_messages = {};//     ,      (persist:false )     ,            ,            

  var id_lookup = {};//         ,  :unsubscribe resubscribe  

  var new_id = 1;// id  

  return {

   'version':'1.0'

   ,'updated_on':'2011-12-19'

   //       arbiter      

   ,'create': function() { return create_arbiter(); }

   //  

   ,'subscribe': function() {

    var msg, messages, subscription_list, persisted_subscription_list, subscription, func, options={}, context, wildcard=false, priority=0, id, return_ids=[];

    if (arguments.length<2) { return null; }

    messages = arguments[0];

    // Function is always last argument

    //               

    func = arguments[arguments.length-1]; 

    //      

    if (arguments.length>2) { options = arguments[1] || {}; }

    //       

    if (arguments.length>3) { context = arguments[2]; }



    //   ,   ,      

    if (options.priority) {

     priority = options.priority;

    }

    //       (topic)

    if (typeof messages=="string") {

     messages = messages.split(/[,\s]+/);//","        

    }

    for (var i=0; i<messages.length; i++) {

     msg = messages[i];

     // If the message ends in *, it's a wildcard subscription

     //      *  ,            

     if (/\*$/.test(msg)) {

      wildcard = true;

      msg = msg.replace(/\*$/,'');

      //           

      subscription_list = wildcard_subscriptions[msg];    

      if (!subscription_list) {

       wildcard_subscriptions[msg] = subscription_list = [];

      }

     }

     else {

      //        

      subscription_list = subscriptions[msg];    

      if (!subscription_list) {

       subscriptions[msg] = subscription_list = [];

      }

     }

     // id    

     id = new_id++;

     //        

     subscription = {'id':id,'f':func,p:priority,self:context,'options':options};

     //          

     id_lookup[id] = subscription;

     //        

     subscription_list.push ( subscription );

     // Sort the list by priority

     //   priority      

     subscription_list = subscription_list.sort( function(a,b) {

      return (a.p>b.p?-1:a.p==b.p?0:1);

     } );

     // Put it back in after sorting

     //                       

     if (wildcard) {

      wildcard_subscriptions[msg] = subscription_list;

     }

     else {

      subscriptions[msg] = subscription_list;

     }

     //  id  “         ”

     return_ids.push(id);

     

     // Check to see if there are any persistent messages that need

     // to be fired immediately

     //       persist  ,           ,           ,          

     if (!options.persist && persistent_messages[msg]) {/// bug? !options.persist       options.persist 

      persisted_subscription_list = persistent_messages[msg];

      for (var j=0; j<persisted_subscription_list.length; j++) {

       subscription.f.call( subscription.self, persisted_subscription_list[j], {persist:true} );

      }

     }

    }

    // Return an array of id's, or just 1

    //     id  id  ,         

    if (messages.length>0) {

     return return_ids;

    }

    return return_ids[0];

   }

   

   //    

   ,'publish': function(msg, data, options) {

    var async_timeout=10,result,overall_result=true,cancelable=true,internal_data={},subscriber, wildcard_msg;

    //              

    var subscription_list = subscriptions[msg] || [];

    options = options || {};

    // Look through wildcard subscriptions to find any that apply

    //          

    for (wildcard_msg in wildcard_subscriptions) {

     //

     if (msg.indexOf(wildcard_msg)==0) {

      subscription_list = subscription_list.concat( wildcard_subscriptions[wildcard_msg] );

     }

    }



    //            

    if (options.persist===true) {

     //             

     if (!persistent_messages[msg]) {

      persistent_messages[msg] = [];

     }

     persistent_messages[msg].push( data );

    }

    //

    if (subscription_list.length==0) { 

     return overall_result; 

    }

     //                 

    if (typeof options.cancelable=="boolean") {

     cancelable = options.cancelable;

    }

    //        

    for (var i=0; i<subscription_list.length; i++) {

     subscriber = subscription_list[i];

     //       unsubscribed  ,                 

     if (subscriber.unsubscribed) { 

      continue; // Ignore unsubscribed listeners

     }

     try {

      // Publisher OR subscriber may request async

      //   Publisher                  ,               

      if (options.async===true || (subscriber.options && subscriber.options.async)) {

       //  setTimeout    

       // async_timeout:               

       setTimeout( (function(inner_subscriber) {

        return function() {

         inner_subscriber.f.call( inner_subscriber.self, data, msg, internal_data );

        };

       })(subscriber), async_timeout++ );

      }

      else {

       //              ,          false,     ,         

       result = subscriber.f.call( subscriber.self, data, msg, internal_data );

       if (cancelable && result===false) {

        break;

       }

      }

     }

     catch(e) {

      //     false

      overall_result = false;

     }

    }

    //     false

    return overall_result;

   }

   

   //       

   ,'unsubscribe': function(id) {

    if (id_lookup[id]) {

      id_lookup[id].unsubscribed = true;

      return true;

    }

    return false;

   }

   

   //     

   ,'resubscribe': function(id) {

    if (id_lookup[id]) {

      id_lookup[id].unsubscribed = false;

      return true;

    }

    return false;

   }

   

  };

 };

 return create_arbiter();

 

})();
能力に限りがありますので、間違いがあれば指摘してください.
注:転載は出典を明記してください.ご飯泥棒猫メール: 
[email protected]