模块化开发往往最大的问题是解耦,怎么设计一个低耦合的组件呢?这里我用到的方法是时间总线(eventBus
)方法,也可以叫做广播事件,模块之间通过发送广播的方式来实现通信,事件发起者只需要派发事件,而不必关心事件是否被接收(订阅)。
广播事件也是自定义事件的一种,不同于自定义事件,广播事件没有绑定的主体,但是都是通过观察者设计模式来写的代码。
大体的javascript实现代码如下:其中包括一些简单方法没有列出,例如$.isUndefined
var _cache = {};
var broadcast = {
/**
* 派发
* @param {[type]} type 事件类型
* @param {[type]} data 回调数据
* @return {[type]} [description]
*/
fire:function(type, data){
var listeners = _cache[type],len = 0;
if(!$.isUndefined(listeners)){
var args = [].slice.call(arguments);
args = args.length > 2 ? args.splice(2, args.length-1) : [];
args = [data].concat(args);
len = listeners.length;
for(var i = 0; i<len;i++){
var listener = listeners[i];
if(listener && listener.callback) {
args = args.concat(listener.args);
listener.callback.apply(listener.scope, args);
}
}
}
return this;
},
/**
* 订阅广播事件
* @param {[type]} types 事件类型,支持,分隔符
* @param {Function} callback 回调函数
* @param {[type]} scope 回调函数上下文
* @return {[type]} this
*/
subscribe:function(types, callback, scope){
types = types || [];
var args = [].slice.call(arguments);
if($.isString(types)){
types = types.split(',');
}
var len = types.length;
if(len===0){
return this;
}
args = args.length > 3 ? args.splice(3, args.length-1) : [];
for(var i = 0;i<len;i++){
var type = types[i];
_cache[type] = _cache[type] || [];
_cache[type].push({callback:callback,scope:scope,args:args});
}
return this;
},
/**
* 退订
* @param {[type]} type [description]
* @param {Function} callback 假如传入则移出传入的监控事件,否则移出全部
* @return {[type]} [description]
*/
unsubscribe:function(type, callback, scope){
var listeners = _cache[type];
if (!listeners) {
return this;
}
if(callback){
var len = listeners.length,
tmp = [];
for(var i=0; i<len; i++) {
var listener = listeners[i];
if(listener.callback == callback && listener.scope == scope) {
} else {
tmp.push(listener);
}
}
listeners = tmp;
}else{
listeners.length = 0;
}
return this;
},
/**
* 订阅别名
* @return {[type]} [description]
*/
on:function(){
return this.subscribe.apply(this,arguments);
},
/**
* 退订别名
* @return {[type]} [description]
*/
un:function(){
return this.unsubscribe.apply(this,arguments);
},
dispatch:function(){
return this.fire.apply(this,arguments);
},
removeAll:function(){
_cache = {};
return this;
}
};
使用方法:
broadcast.fire('event name', json);
broadcast.on('event name', function(data){
console.log(data);
});