回想上一章的通用的发布—订阅模式,我们给Event对象及saleOffices对象都添加了订阅—发布的功能,这里存在两个问题。
1.我们给每个发布者对象都添加了listen和trigger方法,以及一个缓存列表clientList,这其实是一种资源浪费。
2.小明跟售楼处对象还是存在一定的耦合性,小明至少要知道售楼处对象的名字是saleOffices,才能顺利的订阅到事件
事实上,发布——订阅模式可以用一个全局的Event对象来实现,订阅者不需要了解消息来自哪个发布者,发布者也不需要消息会推送到哪些订阅者, Event作为一个类似”中介者“的角色,把订阅者和发布者联系起来。代码如下:
<script> var Event = (function(){ var clientList = {}, listen, trigger, remove; listen = function( key, fn ){ if( !clientList[ key ] ){ clientList[ key ] = []; }; clientList[ key ].push( fn ); }; trigger = function(){ var key = Array.prototype.shift.apply( arguments ), fns = clientList[ key ]; if( !fns || fns.length === 0 ){ return false; } for( var i = 0, fn; fn = fns[ i++ ]; ){ fn.apply( this, arguments ) } }; remove = function( key, fn){ var fns = clientList[ key ]; if( !fns ){ return false; } if( !fn ){ clientList[ key ] = []; }else{ for( var i = 0; i < fns.length; i++ ){ if( fn === fns[ i ]){ fns.splice( i, 1); } } } }; return { listen: listen, trigger: trigger, remove: remove } }()); Event.listen( "squareMeter88", fn1 = function( price ){ console.log( price ); } ); Event.remove( "squareMeter88",fn1 ); Event.trigger( "squareMeter88", 200000 ); </script>