多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
<hr> <div id="div1"><h3> <font color=red> 发布订阅模式--观察者模式 </font> <h3></div> 分离事件创建者和执行者,执行方只需订阅感兴趣的事件发生点。减少对象间的耦合关系,新的订阅者出现时不必修改原有代码逻辑 发布订阅模式,它定义了对象间一种一对多的关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。 应用: 浏览器的dom事件通知机制(document.addEventListener),以及vue框架中数据改变时自动刷新dom的双向绑定机制 ```javascript var Event = function () { var clientList = {} // 订阅者数组 this.listen = function (key, cb) { // 订阅方法 clientList[key] = clientList[key] || [] clientList[key].push(cb) } this.remove = function (key, cb) { // 取消订阅 var fns = clientList[key] if(!cb) { clientList[key] = [] }else if(fns && fns.length) { clientList[key] = fns.filter(fn => fn !== cb) } } this.trigger = function () { // 通知订阅者 var key = Array.prototype.shift.call(arguments) var args = arguments var fns = clientList[key] var _this = this if(fns && fns.length) { fns.myEach(function(fn) { fn.apply(_this, args) }) } } } var event = new Event() event.listen('phone', function getPhone() { Array.prototype.unshift.call(arguments, '有个挨千刀的半夜打电话来了他是:') console.log.apply(this, arguments) }) event.trigger('phone', '大狗子') // 有个挨千刀的半夜打电话来了他是:大狗子 event.trigger('phone', '二狗子') // 有个挨千刀的半夜打电话来了他是:二狗子 ``` ```js const JasonMa_PubSub = { listenStore: {}, on: function(method, cb) { if (this.listenStore[method]) { this.listenStore[method].push(cb); } else { this.listenStore[method] = [cb]; } }, emit: function(method, ...args) { const fnList = this.listenStore[method]; if (!fnList || fnList.length === 0) { return false; } else { fnList.forEach(cb => { cb.apply(this, args); }); } }, off: function(method) { const fnList = this.listenStore[method]; if (fnList && fnList.length !== 0) { delete this.listenStore[method]; } }, once: function(method, cb) { let onceFn = (...args) => { cb.apply(this, args); this.off(method); }; this.on(method, onceFn); } }; export default JasonMa_PubSub; //es6引入 import pubsub from './JasonMa_PubSub.js' pubsub.on("abc", function(...args) { console.log("abc触发了", args); }); pubsub.once("aaaaa", function(...args) { console.log("aaaaa触发了", args); }); setInterval(() => { pubsub.emit("abc", 1, 2, 3, 4); pubsub.emit("aaaaa", "我是aaaaa的数据"); }, 1500); setTimeout(() => { pubsub.off("abc"); }, 5000); ```