Open coleava opened 3 years ago
发布订阅模式:基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。
发布订阅模式与观察者模式的不同,“第三者” (事件中心)出现。目标对象并不直接通知观察者,而是通过事件中心来派发通知。
let pubSub = { // 控制中心 list: {}, // 订阅 subscribe: function(key, fn) { if (!this.list[key]) this.list[key] = []; this.list[key].push(fn); }, //取消订阅 unsubscribe: function(key, fn) { let fnList = this.list[key]; if (!fnList) return false; if (!fn) { // 不传入指定的方法,清空所用 key 下的订阅 fnList && (fnList.length = 0); } else { fnList.forEach((item, index) => { item === fn && fnList.splice(index, 1); }); } }, // 发布 publish: function(key, ...args) { for (let fn of this.list[key]) fn.call(this, ...args); } } // 订阅 pubSub.subscribe('onwork', time => { console.log(`上班了:${time}`); }) pubSub.subscribe('offwork', time => { console.log(`下班了:${time}`); }) pubSub.subscribe('launch', time => { console.log(`吃饭了:${time}`); }) pubSub.subscribe('onwork', work => { console.log(`上班了:${work}`); }) // 发布 pubSub.publish('offwork', '18:00:00'); pubSub.publish('launch', '12:00:00'); // 取消订阅 pubSub.unsubscribe('onwork');
DOM 的事件监听是“发布订阅模式”:
let loginBtn = document.getElementById('#loginBtn');
监听回调函数(指定事件) function notifyClick() { console.log('我被点击了'); } // 添加事件监听 loginBtn.addEventListener('click', notifyClick); // 触发点击, 事件中心派发指定事件 loginBtn.click(); // 取消事件监听 loginBtn.removeEventListener('click', notifyClick);
发布订阅模式:基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。
发布订阅模式与观察者模式的不同,“第三者” (事件中心)出现。目标对象并不直接通知观察者,而是通过事件中心来派发通知。
DOM 的事件监听是“发布订阅模式”:
let loginBtn = document.getElementById('#loginBtn');