发布订阅模式
- 一般用来处理大型项目(框架)的封装
- 自行搜索: vue2.0 响应式实现原理
帮助理解
* 去书店买书 * JS曾经的流程 * 1. 你去到书店,问店员 有没有一本叫做 <JS从入门到入土> * 2. 店员: 我们现在没有,你下次再来 * 3. 过了一段时间后,又去书店 问店员 有没有一本叫做 <JS从入门到入土> * 4. 店员: 我们现在没有,你下次再来 * 5. 过了一段时间后,又去书店 问店员 有没有一本叫做 <JS从入门到入土> * 6. 店员: 我们现在没有,你下次再来 * ...... * 89. 过了一段时间后,又去书店 问店员 有没有一本叫做<JS从入门到入土> * 90. 店员: 在XX位置有,你去拿吧 * 发布订阅模式: * 1. 你去到书店,问店员 有没有一本叫做 <JS从入门到入土> * 2. 店员: 我们现在没有,然后你留下一个联系方式,将来有了之后我电话通知你 * 3. 过了一段时间后,有书本了,店员通过电话联系到你,触发了你的技能(触发了一个函数)然后购买了书本 * * 'JS从入门到入土': [预约者1, 预约者2, 预约者3] * '颈椎病的预防': [预约1, 预约2, 预约3]
class observer {
constructor(name) {
this.name = name //模拟店员的名字,但是不重要
this.msgList = {} //模拟店员的记录手册
}
// 购买不到书本 留下预约的方式的时候执行
add(type, fn) {
// 通过这个函数可以向this.msgList内添加内容,后续方便维护
if(this.msgList[type] === undefined) {// 当前分支执行,表明这个type是第一次出现
this.msgList[type] = [] //第一次出现的时候,给它赋值一个空数组,后续的内容直接push到数组内就可以了
}
this.msgList[type].push(fn) //此时的 this.msgList[type] 一定是一个数组,所以直接将预约者push到数组中就可以了
}
// 一段时间后,书本到了,通知对应的预约者,然后触发他们的技能(函数)
try(type) {
this.msgList[type].forEach(item => item()) //通过传入的type 找到对应的属性值,然后遍历调用内部的所有函数
}
delName(type, fn) {
// 调用这个方法,取消预约,找到对应的数组,将你的联系方式 删除
this.msgList[type] = this.msgList[type].filter(item => item !== fn)
}
}
const o1 = new observer('小张')
console.log(o1)
// 书名
const bookName1 = 'JS从入门到入土'
const bookName2 = 'JS从入门到入土'
// 预约者的技能(函数)
const fnA = () => console.log('我是张三, 我想购买这本书')
const fnB = () => console.log('我是李四, 我想购买这本书')
const fnC = () => console.log('我是王五, 我想购买这本书')
// 新增两位预约者
o1.add(bookName1, fnA)
o1.add(bookName1, fnB)
o1.add(bookName1, fnC)
// 中间一位预约者取消了预约
o1.delName(bookName1, fnB)
// 过了一段时间,书本到了,通知对应的预约者
o1.try(bookName1)
console.log('有预约者之后的', o1)