从发布订阅者角度理解观察者模式
目的:
让 观察者 看着 被观察者, 只要数据改变了就让 观察者 做一些事情
分为三个状态
- 订阅
- 取消订阅
- 发布
模式的核心思想(重)
-
准备一个消息盒子,存储触发的事件及处理函数的对象
class Observer { constructor () { // 准备的消息盒子 this.message = {} }
-
订阅的方法向消息盒子里面添加内容
on (type, fn) { //向消息盒子里面添加某个成员 }
-
取消订阅的方法,把已经订阅的方法从消息盒子内部拿走
off (type, fn) { //向消息盒子里面删除某个成员 }
-
发布事件的方法把消息盒子里面的对应的处理函数执行了
emit () { //执行消息盒子里面某个对应的处理函数 }
主要代码主动奉上
class Observer {
constructor() {
//准备一个消息盒子
this.message = {};
}
//订阅的方法
on(type, fn) {//向消息盒子里面添加某个成员
// 如果消息盒子里面没有这个事件类型就添加这个事件类型
if (!this.message[type]) {
this.message[type] = [];
}
this.message[type].push(fn);
}
//取消订阅的方法
off(type, fn) {//向消息盒子里面删除某个成员
//先检查在消息盒子里面是否有相应的事件类型,如果没有,则不需要删除
if (!this.message[type]) {
return//直接返回
}
//通过过滤函数,直接过滤掉消息盒子里面的需要删除的成员
this.message[type] = this.message[type].filter(item => item !== fn);
}
//发布的方法
emit(type, ...arg) {//执行消息盒子里面某个对应的处理函数
//如果没有该事件类型,就直接返回
if (!this.message[type]) { return }
//自己组装一个事件对象
//这个里面所有的数据都是传递可以传递给数件处理函数使用的内容
var event = {
type: type,
//参数
data: arg
}
//调用每一个时间处理函数的时候,都带上一个事件对象
this.message[type].forEach(item => item())
}
}
// 实现随便准备几个事件处理函数
//e是用来接收emit里面调用的时候传递的event对象
// ,对象里面的数据就是在触发事件的时候传递进来的数据
function handlerA(e) { console.log('我是事件处理函数 handlerA',e)}
function handlerB(e) { console.log('我是事件处理函数 handlerB',e)}
function handlerC(e) { console.log('我是事件处理函数 handlerC',e)}
function handlerD(e) { console.log('我是事件处理函数 handlerD',e)}
function handlerE(e) { console.log('我是事件处理函数 handlerE',e)}
//使用订阅者
var observ = new Observer()
//订阅事件
observ.on('click', handlerA);
observ.on('click', handlerB);
observ.on('click', handlerC);
observ.on('click', handlerD);
observ.on('abc', handlerE);
observ.on('abc', handlerA);
console.log(observ);
//触发一下事件
observ.emit('click');