赞
踩
定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。在js中,一般用事件模型来替代传统的发布-订阅模式
// 将发布---订阅的功能提取出来 let event = { // 缓存列表,存放订阅者订阅的事件和其回调函数 clientList:{}, // 增加订阅者订阅的事件和回调函数 listen(key,fn){ if(!this.clientList[key]){ //如果没有订阅过此类消息,则给该类消息创建一个缓存列表 this.clientList[key] = []; } // 将订阅消息添加进消息缓存列表 this.clientList[key].push(fn); }, // 发布消息 on(...args){ let key = args.shift(), fns = this.clientList[key]; if( !fns || fns.length === 0 ){ //没有绑定对应消息 return false; } for(let fn of fns){ //通知订阅该消息的所有订阅者 fn.call(this,args); //args是trigger时带上的参数 } }, // 取消订阅 off(key,fn){ let fns = this.clientList[key]; if(!fns){ return false; //key对应的消息没有被人订阅,直接返回 } if(!fn){ //没有传入fn,则表示取消key对应消息的所有订阅 fns && ( fns.length=0 ) }else{ let index = fns.findIndex(function(val){ return val===fn; }); fns.splice(index,1); //删除订阅者的回调函数 console.log('success'); } } }; // 给所有对象都动态安装订阅-分布功能 let installEvent = obj=>{ for( let key in event ){ obj[key] = event[key]; } }; let salesOffice = {}; installEvent(salesOffice); salesOffice.listen('square88',fn1=price=>console.log('price='+price)); salesOffice.listen('square88',fn2=price=>console.log('price='+price)); salesOffice.on('square88',8000); salesOffice.off('square88',fn1); salesOffice.on('square88',8000);
// 全局发布--订阅对象 let Event = { // 缓存列表,存放订阅者的回调函数 clientList:{}, // 增加订阅者--监听 listen(key,fn){ if(!this.clientList[key]){ //如果没有订阅过此类消息,则给该类消息创建一个缓存列表 this.clientList[key] = []; } // 将订阅消息添加进消息缓存列表 this.clientList[key].push(fn); }, // 发布消息 trigger(...args){ let key = args.shift(), fns = this.clientList[key]; if( !fns || fns.length === 0 ){ //没有绑定对应消息 return false; } for(let fn of fns){ //通知订阅该消息的所有订阅者 fn.call(this,args); //args是trigger时带上的参数 } }, // 取消订阅 remove(key,fn){ let fns = this.clientList[key]; if(!fns){ return false; //key对应的消息没有被人订阅,直接返回 } if(!fn){ //没有传入fn,则表示取消key对应消息的所有订阅 fns && ( fns.length=0 ) }else{ let index = fns.findIndex(function(val){ return val===fn; }); fns.splice(index,1); //删除订阅者的回调函数 console.log('success'); } } }; Event.listen('88',price=>console.log('price='+price)); Event.trigger('88',88888); // 模块间通信,每次点击a模块里面的按钮,b模块显示按钮点击次数 // 将b订阅的事件添加到全局发布--订阅对象 let b=(()=>{ let div = document.getElementById('show'); Event.listen('add',count => div.innerHTML=count ); })() // 通过a触发全局发布--订阅对象发布消息 let a = (()=>{ let count = 0; let button = document.getElementById('count'); button.addEventListener('click',()=>Event.trigger('add',count++)) })()
上面利用全局发布–订阅对象实现模块间通信
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。