观察者模式(Observer)
又称作为发布-订阅模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者对象之间通讯和耦合的问题;
观察者模式例子 引用于<JavaScript设计模式>
var Observer = (function(){ var _messages = {}; // 监听信息容器 return { /** * 注册监听信息接口 * @param {String} type 监听信息类型 * @param {Function} fn 对应的回调函数 */ regist: function(type, fn){ // 如果过目前没有该类信息 创建数组添加 如果已经存在该类信息通过push数组添加避免覆盖 if(typeof _messages[type] === ‘undefined‘){ _messages[type] = [fn]; }else{ _messages[type].push(fn); } }, /** * 发布信息接口 * @param {String} type 发布相关信息,触发所有该信息的回调函数 * @param {Object} args 传给回调函数的信息参数 */ fire: function(type, args){ // 如果该类信息没有注册信息则,直接返回 if(!_messages[type]) return; // 通过args参数定义 响应事件的事件对象 var event = { type: type, args: args || {}, }, i = 0, len = _messages[type].length; for(;i < len; i++){ // 传入参数调用 回调函数 _messages[type][i].call(this,event); } }, /** * 移除监听信息 * @param {String} type * @param {Function} fn */ remove: function(type,fn){ if(_messages[type] instanceof Array){ var i = _messages[type].length-1; for(;i>=0;i--){ // 遍历该类型的函数 找出对应的 函数并删除 _messages[type][i] === fn && _messages[type].splice(i,1); } } }, }; })(); // 观察者->主题:今天中午吃什么菜呢,中午开饭的时候告诉我 function getFoodMenu(obj){ console.log(‘今天的吃的是:‘+obj.args.foodMenu) } Observer.regist(‘lunch‘,getFoodMenu ); // 主题->观察者: 开饭了 ,今天只有番茄鸡蛋/豆腐汤 呵呵~~ Observer.fire(‘lunch‘,{ foodMenu: ‘番茄鸡蛋,豆腐汤‘, }); // 调用getFoodMenu ==打印==> 今天的吃的是:番茄鸡蛋,豆腐汤
从用法上简单的总结就是,添加回调函数和触发回调函数
DOM事件也是同样的原理
注册监听: addEventListener(type,fn)注册事件
取消监听: removeEventListener(type,fn)
当主体发布消息时传入Event事件对象z执行回调函数
DOM事件和自定义事件 区别:自动发布信息 , 手动发布信息
DOM事件类型是固定的 click / mmouseover / keydown ....
当DOM受到相关操作的时候DOM节点自动发布信息 ,触发回调函数
而自定义事件,而自定义事件需要创建事件对象,再去手动的发布信息触发回调函数
Promise也有类似的原理