javascript 用事件驱动解耦
日常开发中如果页面交互过于复杂,我们经常会采用分模块的的方法把程序分为多个模块来处理,
比如我们把一个页面分为 A , B , C 三个模块,各模块之间往往又会有所关联,比如 A 模块执行完一个
方法后B模块和C模块同时做出响应,这就是所谓的耦合。以下代码经常出现在程序中。如
[javascript]
var A = {
test:function(){
console.info('A.test');
B.test();
C.test();
}
};
var B = {
test:function(){
console.info('B.test');
}
};
var C = {
test:function(){
console.info('C.test');
}
};
[/javascript]
这样写本来没什么,但逻辑过于复杂之后就很难维护,常常会把人搞晕。
观察者模式很好的处理了这个问题,它把模块之间耦合的地方全部抛到一个
统一的地方来处理。可以随时订阅和解订,以下是通过事件的方式实现的一个
统一处理事件的中心,所有耦合的地方在此处理,程序内部只需发布事件。
[javascript]
var hub = {
subscribe:function(obj,name,handler){
if(!obj.hasOwnProperty('_e_')) obj._e_ = {};
if(obj._e_[name]) obj._e_[name].push(handler);
else obj._e_[name]=[handler];
},
unsubscribe:function(obj,name){
delete obj._e_[name];
},
publish:function(obj,name,parameter){
if(!obj._e_.hasOwnProperty(name)) return;
var i = 0,len = obj._e_[name].length;
while(len!==i){
obj._e_[name][i].apply(obj,[].slice.call(arguments,2));
i++;
}
}
};
[/javascript]
以下是使用方法,a 对象与x,y对象的耦合已经被抛出来。。。
[javascript]
var a = {
test:function(){
console.info('a.test is run');
//发布事件
hub.publish(this,'testX',1,2,3,4,4,54,5);
hub.publish(this,'testY',1,2,3,4,4,54,5);
}
};
var x = {
test:function(){
console.info('i am a observer, and named x.test');
}
};
var y = {
test:function(){
console.info('i am a observer too, and named y.test');
}
};
//订阅事件,处理耦合
hub.subscribe(a,'testX',function(a,b,c,d,e,f,g){
x.test(arguments);
});
hub.subscribe(a,'testY',function(){
y.test(arguments);
});
a.test();
[/javascript]