在网上看了一些关于订阅/发布模式的代码,发现其中有一些有很多错漏,遂自己写了一个例子,先上代码
var listen = {}; listen.objer={};//事件对象,存放事件和每次事件之后的调用函数组成的指针数组 listen.sub=function(evt,fn){//订阅的方法,成功了返回订阅标志 if (!listen.objer[evt]) { return -1; } else{ listen.objer[evt].push(fn); return { 'event':evt, 'flag':listen.objer[evt].length-1 }; } } listen.pub=function(evt){//发布的方法 listen.objer[evt]?call(evt):0; function call(evt){ var collector = listen.objer[evt]; var length = collector.length; for(var i =0;i<length;i++){ //alert(1); //setTimeout(collector[i](),0); collector[i]() } } } listen.unsub = function(o){ var Event = o.event; alert(Event); listen.objer[Event]?(delete listen.objer[Event][o.flag]):0; } listen.addevent = function(evt){ listen.objer[evt]?0:listen.objer[evt]=[]; return listen.objer; }
发布/订阅者模式其实很好理解,特别是你理解了js的事件轮询和jsonp的用法之后,你就会发现这两者的核心就构成来所谓的发布/订阅模式。
先说说关于
//setTimeout(collector[i](),0);
这句被我我注释掉了,那么我之前为什么要这么写呢,我是出于一种考虑,如果在事件轮询中遇到一个函数,其执行的时间很长,那么会发生什么,会堵塞,,甚至会影响下一次事件的发布,我本来寄希望于setTimeout就像新开了一个线程一样,将这个问题解决的,然后并不可行,因为setTimeout会等前面的回调函数执行完了才会继续执行,setInterval尽管可以跳过执行很长的函数,可是他有副作用,这个问题暂时还没有什么好的法子,我会再研究。或者,可以有什么方法识别执行很长的函数,然后杀掉它。
还有关于setTimeout如果你传字符串,那么要注意不要使用局部变量,读不到的。
此外,js里有一种说法,说是js里对象很慢,我觉得这个要分情况分析,如果你的对象原型链很深,那么相应的自然慢,如果只是简单的对象字面量,我觉得对象用来索引还是很高效的