参考https://juejin.cn/post/6844903496093794317
1、观察者模式,定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它(改变的状态)的对象都会得到通知。
2、发布订阅模式,订阅者把想订阅的事件注册到调度中心,当该事件触发的时候,发布者发布该事件到调度中心(顺带上下文),由调度中心统一调度订阅者曾经注册到调度中心的处理代码。
定义调度中心函数对象:
1、使用一个对象作为调动中心的缓存clientList,
2、add方法负责把订阅的事件注册到调度中心的缓存中,用来存放订阅者的回调函数以便通知到订阅者
3、tigger方法负责发布消息时,遍历缓存,依次触发里面的回调函数
4、delete方法负责,取消之前的订阅。
const subscribe = (function(){ let clientlist = {}, add, trigger,remove; /** * 增加订阅者, * @key {string}类型 * @fn {function}类型 */ /** * 订阅 */ add = function(key, fn) { if(!clientlist[key]){ clientlist[key]=[]; } clientlist[key].push(fn); } /** * 发布 */ trigger = function(){ console.log(arguments); let key = [].shift.call(arguments); /** * 取出消息类型,“删除并拿到arguments的第一项”; * shift 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。 * 等于 Array.protoType.shift.call(arguments); */ let fns = clientlist[key]; console.log('key ====', key); console.log('key ====', key); if(!fns || fns.length === 0){ return false; } for (let i = 0,fn;fn=fns[i++];) { fn.apply(this,arguments); // 依次执行发布的消息 } } /** * 删除订阅 * key{string}类型 * fn{function}回调函数 */ remove = function(key, fn){ let fns = clientlist[key]; // 取出该类型的对应的消息集合 if(!fns) { return false; } if(!fn){// 如果没有传入具体的回调函数,则表示要取消所有的订阅 fn && (fns.length = 0) } else{ for(let j = fns.length-1;j>=0;j--){ if(fn===fns[j]){ fn.splice(j,) } } } } return{ addListen:add, trigger, remove } })()
//添加订阅 subscribe.addListen('key1',function(d , all){ console.log(d + "长了一"+ all) }) subscribe.addListen('key2',function(d, all){ console.log(d+"喜欢做的事情是"+all) })
// 发布消息 subscribe.trigger('key1','luhan','娃娃脸'); //luhan长了一娃娃脸 subscribe.trigger('key2','wuyifan','耍帅'); // wuyifan喜欢做的事情是耍帅