观察者模式简介:
观察者模式又被称为发布订阅模式。是一种一对多的依赖关系,也就是某一个对象(消息发布者)的状态发生改变时,其他的对象(订阅者)接收到消息后会自动执行各自的操作。
该模式中涉及到的对象:
1.消息发布者(一个)
1.1消息发布者首先会建立一个通知数组arr,用来存储订阅者信息对象(有订阅该消息的观察者obj以及obj对应操作的回调函数callback)
1.2消息发布者角色职责:
(1)制定订阅该消息的方法
(2)制定取消订阅消息的放方法
(3)消息发布
2.订阅者(众多):订阅者触发某事件时,让消息发布者调用订阅方法(此时订阅者会[传入回调函数及订阅者对象自己],然后被加入到通知数组中)。
画图简介:
代码详解:
// 创建观察者模式
// 1.创建一个消息发布者对象pubSub
var pubSub = {
//1.1 创建订阅者信息数组
subscriber: [],//存储订阅者信息的数组,包括订阅者和它的行为函数(回调函数)
// 1.2添加订阅的方法
addSub: function(callback, obj) {
this.subscriber.push({ctx: obj,cb: callback});//(将订阅者信息【订阅者和它的行为函数(回调函数)】以对象的形式添加到订阅者信息数组)
},
//1.3取消订阅的方法(遍历订阅者信息数组,移除传入的订阅者信息)
cancelSub:function (obj){
for(var i = 0; i<this.subscriber.length; i++){
if(this.subscriber[i].ctx === obj ){
this.subscriber.splice(i,1);
break;
}
}
},
// 1.4发布消息(遍历,传递数据给每个订阅者对象,然后订阅者对象各自调用自己的行为函数)
pub: function(data) {
for(var i = 0; i < this.subscriber.length; i++) {
// 发布消息的时候,消息发布者把消息(数据data传参给每个对象的回调函数,并调用该回调函数)
this.subscriber[i].cb.call(this.subscriber[i].ctx, data);//注意:这里每个订阅者对象的回调函数在这里被调用的时候,回调函数本身内部的this指向被改变了(原本应该指向的是实例对象obj(订阅者,例如s1),在这里被指向了调用回调函数的this.subscriber[i]【也就是包含订阅者对象和它方法的外层对象】),所以这里需要借助call来改变回调函数this.subscriber[i].cb内部this的指向,让它指向this.subscriber[i].ctx,所以不能写成这种this.subscriber[i].cb(data);
}
}
};
//2.订阅者订阅及取消
//订阅
document.querySelector("#btnBJ").onclick = function() {
pubSub.addSub(fn, s3);//当点击订阅按钮的时候,消息发布者调用订阅方法
this.disabled = true;//订阅按钮不可用
document.querySelector("#btnBJcancel").disabled = false;//取消订阅按钮可用
};
//取消订阅
document.querySelector("#btnBJcancel").onclick = function (){
pubSub.cancelSub(s3);//点击取消订阅按钮的时候,消息发布者调用取消订阅方法
this.disabled = true;
document.querySelector("#btnBJ").disabled = false;
}