javascript 使用事件路由对模块解耦
最近接手,维护起来非常吃力,如果要增加一个功能,需要从头改到尾,更让人崩溃的是,在这个页面中使用了不七八个全局变量进行状态标识。这个页面的规模已经可以算是一个中小应用的规模。对下调用底层话路OCX对象,进行各种话路功能的调用,并处理底层话路OCX的状态。对上则相应用户的操作,并更新UI。
举个例子,现在的情况是:
假如有AB两个模块,现在AB两个模块的状态是硬编码在一起的:
if(A.A1){ B.B1(); } if(A.A2){ B.B2(); }
如果增加模块C,C的状态是由A的状态控制的,目前要实现C的功能则需要修改A模块的代码:
if(A.A1){ B.B1(); C.C1(); } if(A.A2){ B.B2(); C.C2(); }
状态一多,模块一多,维护起来就是一个噩梦。
针对这种情况,使用事件机制,即使一个很简单的一种,也可以大大改观目前的这个状况。
我自己实现了一个简单版本的详细路由器:
(function(window){ var eventsQueue = {}, Component = function(){}; Component.prototype={ on:function(event,callback){ if(eventsQueue[event] && eventsQueue[event].push){ eventsQueue[event].push(callback); } else{ eventsQueue[event] = [callback]; } return this; }, emit:function(event,data){ if(eventsQueue[event] && eventsQueue[event].push){ for(var i=2; i<eventsQueue[event].length; i++){ eventsQueue[event][i].call(data); } } return this; } }; window.Component = Component; }(window));
这样模块间状态的依赖,通过事件通知进行触发,当增加新模块时,不用再修改原来的代码。
var A = new Component(); var B = new Component(); B.on("A1",function(){ B.B1(); }); B.on("A2",function(){ B.B2(); }); var C = new Component(); C.on("A1",function(){ C.C1(); }); C.on("A2",function(){ C.C2(); }); A.emit("A1"); A.emit("A2");
当然这个事件路由的代码很简单,目前有很多非常成熟的开源JS模块专门做事件这一块,比如:amplify 。