发布订阅模式-前端设计模式
首先理解 发布和订阅
利用报刊的场景 小时候,家里人有看报刊的习惯, 会和联系送报刊的人 告诉他,我需要什么类型的报刊。 - 这个可以被称为订阅 接着报刊到了,送报刊的人,会把报刊送到我家。-这属于发布
在程序中怎么来定义的呢? 还是利用数组的方法是实现 type 是 你定义报刊的类型 fn 是一个函数,可以理解为报刊的内容
let event = { add(type, fn) { if (!this[type]) { this[type] = [] } this[type].push(fn) } }
trigger 这个函数 就是调用了我们存在数组里面的函数 它表示发布的意思。
let event = { add(type, fn) { if (!this[type]) { this[type] = [] } this[type].push(fn) }, trigger(type) { if(!this[type]) return this[type].forEach(v => { v() }) } }
下面是完整的实现代码 说下优点和缺点: 这种模式很好的维护和二次开发 它会将不同的功能分开来,低耦合性
缺点 就是 可读性比较差 如果不了解这种模式的,第一次看起来就很会不理解
其实 promise.all方法也是发布订阅的思想在里面
let event = { add(type, fn) { if (!this[type]) { this[type] = [] } this[type].push(fn) }, trigger(type) { if(!this[type]) return this[type].forEach(v => { v() }) } } var btn = document.querySelector("#btn") btn.addEventListener(click, function () { console.log(登录成功); event.trigger(login) }) event.add(login, function () { console.log(登录之后获取用户头像); }) event.add(login, function () { console.log(登录之后获取用户的历史听歌记录); }) event.add(login, function () { console.log(登录之后给用户推荐歌单); }) event.add(login, function () { console.log(登录之后给用户推荐VIP优惠券); }) console.log(event);
类方法写的发布订阅模式
// 订阅者 class Subject { constructor() { this.state = 0, this.observers = [] } // 获取state的值 不重要 getState() { return this.state } setState(state) { this.state = state this.notifyAllObservers() } notifyAllObservers() { this.observers.forEach((observer=> { observer.update() })) } attach(observer) { this.observers.push(observer) } } class Observer { constructor(name, subject) { this.name = name this.subject = subject this.subject.attach(this) } update() { console.log(`${ this.name} updata, state: ${ this.subject.getState()}`); } } let s = new Subject() let o1 = new Observer(o1, s) let o2 = new Observer(o2, s) let o3 = new Observer(o3, s) s.setState(1) s.setState(2) s.setState(3)