SOURCE

// 全局对象pubsub,具备发布主题、订阅、取消订阅的功能
var pubsub = {};
 
(function(myObject) {
 
    // 存储广播主题
    var topics = {};
 
    // A topic identifier
    var subUid = -1;
 
    // Publish方法,传入主题名称,和主题需要传递的参数
    myObject.publish = function( topic, args ) {
 
        if ( !topics[topic] ) {
            return false;
        }
 
        // 某个主题下的订阅者列举、统计
        var subscribers = topics[topic],
            len = subscribers ? subscribers.length : 0;
 
        while (len--) {
            // 依次执行订阅者队列的订阅者的func方法
            subscribers[len].func( topic, args );
        }
 
        return this;
    };
 
    // Subscribe方法,用于往某个主题topic队列里添加订阅者, 每个订阅者会被保存为一个对象
    // 该对象包括一个uid和该订阅者自定义的函数
    // @return 返回token
    myObject.subscribe = function( topic, func ) {
 
        if (!topics[topic]) {
          // 检测某个主题是否存在
          // 不存在则新建空数组,用于存储观察者对象
            topics[topic] = [];
        }
 
        var token = ( ++subUid ).toString();
        topics[topic].push({
            token: token,
            func: func
        });
        return token;
    };
 
    // Unsubscribe,取消订阅,通过全局唯一的token,遍历所有主题,找到那个token,然后从主题的数组中删除
    myObject.unsubscribe = function( token ) {
        for ( var m in topics ) {
            if ( topics[m] ) {
                for ( var i = 0, j = topics[m].length; i < j; i++ ) {
                    if ( topics[m][i].token === token ) {
                        topics[m].splice( i, 1 );
                        return token;
                    }
                }
            }
        }
        return this;
    };
}( pubsub ));


// 实例
// 一个用于记录订阅者订阅主题和接收到的消息的简单记录器
var messageLogger = function ( topics, data ) {
    console.log( "Logging: " + topics + ": " + data );
};
 
// 订阅者监听它们订阅的主题,一旦新的通知被广播时,它们会执行回调函数,比如messageLogger函数
// 向主体对象中,添加订阅主题和订阅函数
var subscription = pubsub.subscribe( "inbox/newMessage", messageLogger );
 
// 发布者负责向应用发布或通知,比如下面这个三个发布:
pubsub.publish( "inbox/newMessage", "hello world!" );
 
// or
pubsub.publish( "inbox/newMessage", ["test", "a", "b", "c"] );
 
// or
pubsub.publish( "inbox/newMessage", {
  sender: "hello@google.com",
  body: "Hey again!"
});
 
// 取消订阅
pubsub.unsubscribe( subscription );
 
// 一旦取消订阅,下面发布者发布的消息,不会被打印
pubsub.publish( "inbox/newMessage", "Hello! are you still there?" );




console 命令行工具 X clear

                    
>
console