+ 有一个对象,有人一直看着他
+ 当这个对象发生变化的时候,第三方通知这个看着的人,触发技能
+ 例子:买书
1.普通程序员买书
=> 去书店,问,没有
=> 回家
=> 过一会再去,没有,回家
2.发布订阅的程序员
=> 去书店,问,没有,留下一个联系方式给店员
=> 一旦有了书,就会接到电话
=> 触发技能去买书
+ 只需要一个构造函数
=> 创建一个第三方店员的身份
=> 我们的任务就是模拟一个 addEventListener()
分析构造函数
+ 属性:消息队列
{
click:[fn1,fn2],
abc:[fn1,fn2,fn3]
}
+ 方法:能向消息队列里面添加内容
+ 方法:删除消息队列里面的内容
// 创建一个第三方观察者构造函数
class Observer{
constructor(){
this.message = {
}
}
// 1.向消息队列里面添加内容
on(type,fn){
// type 我拜托你看着的行为
// fn 我让你在行为发生的时候做的事情
// 就应该把写着记录在队列
// 1.判断message里面有没有这个行为已经被注册过了
// 如果没有,我应该给你赋值一个行为,赋值为[]
// 如果有,直接向数组里添加就可以了
if(!this.message[type]){
// 表示消息队列里面还没有注册过
this.message[type] = []
}
this.message[type].push(fn)
// 直接进行push
}
// 2.删除消息队列里面的内容
off(type,fn){
// 判断 如果 fn 不存在,只有 一个参数的清空
if(!fn){
// 直接把这个事情取消掉
// 从 message 里面把 a 成员删除掉就好了
delete this.message[type]
return
}
// 代码能来到这里,表示 fn 存在
// 判断你是不是真的订阅过
if(!this.message[type]) return
// 你确实订阅过,我就可以使用filter删除
this.message[type] = this.message[type].filter((item)=>{ return item!==fn })
}
// 3.触发消息队列
emit(type){
// 判断是不是有订阅过
if(!this.message[type]) return
// 找到这个数组,把里面的每一个函数触发
this.message[type].forEach(fn => {
// fn 就是每一个函数
fn()
});
}
}
// 使用构造函数创建一个实例
const person1 = new Observer()
// 当你想拜托这个 person1 帮你观察一些内容的时候
// 告诉你一个行为,当行为出现的时候,告诉你干什么
person1.on('a',handlerA)
person1.on('a',handlerB)
// 告诉person1,我这个事情不用你管了
// 1.我只告诉你这个事情不用你管了
// person1.off('a') //把 消息队列 里面属于 a 的数组清空掉
person1.off('a',handlerA) //告诉你a发生的时候,不用做handlerA这个事情了
// person1 这个人一旦触发a行为,就要把后面的所有事件处理函数执行掉
person1.emit('a')
function handlerA(){console.log('handlerA')}
function handlerB(){console.log('handlerB')}
function handlerC(){console.log('handlerC')}
function handlerD(){console.log('handlerD')}
function handlerE(){console.log('handlerE')}
function handlerF(){console.log('handlerF')}