发布订阅模式
一般用来处理 大型项目(框架)的封装
去书店买书
-
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) {
if (this.msgList[type] === undefined) { // 当前分支执行, 表明这个 type 是第一次出现
this.msgList[type] = [] // 在第一次出现的时候, 给它赋值一个空数组, 后续的内容直接 push 到数组内就可以了
}
this.msgList[type].push(fn) // 此时的 this.msgList[type] 一定是一个数组, 所以直接将预约者push到数组中就可以了
}
// 一段时间后, 书本到了, 通知对应的预约者, 然后触发他们的技能(函数)
tri(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 = '颈椎病的预防'
// 预约者的技能(函数)
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.tri(bookName1)
console.log('有预约者之后的对象: ', o1)