关于javascript:发布订阅模式和观察者模式

59次阅读

共计 1777 个字符,预计需要花费 5 分钟才能阅读完成。

公布 / 订阅模式

  • 订阅者
  • 发布者
  • 事件核心

咱们假设,存在一个“事件核心”,某个工作执行实现,就向事件核心“公布”(publish)一个事件,其余工作能够向事件核心“订阅”(subscribe)这个事件,从而晓得什么时候本人能够执行。这就叫做“公布 / 订阅模式”(publish-subscribe pattern)

// vue 实现的地方事件总线

let vm = new Vue()

// {'dataChange': [fn1, fn2], 'handleData: [fn]' }
// 注册事件(订阅音讯)vm.$on('dataChange', () => {console.log('dataChange1')
})

vm.$on('dataChange', () => {console.log('dataChange2')
})

// 触发事件(公布音讯)vm.$emit('dataChange')

上面实现一个公布订阅:

// 手写实现公布订阅

// 事件触发器
class EventEmitter {constructor () {// { 'click': [fn1, fn2], 'change: [fn]' }
        // 用一个对象来贮存事件订阅信息,同一个事件可被订阅屡次,故事件的回调函数用数组贮存
        this.subs = Object.create(null)
    }
    
    // 注册事件
    $on (eventType, handler) {
        // 须要找到贮存事件订阅信息对象里是否有以后事件,有则获取已有数组,否则赋值为空数组
        this.subs[eventType] = this.subs[eventType] || []   
        // 新注册事件处理函数
        this.subs[eventType].push(handler)
    }
    
    // 触发事件
    $emit (enventType) {
        // 先判断是否有以后事件,有则执行,没有则不作解决
        if(this.subs[eventType]){
            // 遍历数组调用事件函数
            this.subs[eventType].forEach(handler => {handler()       
            })
        }
    }
}

const em = new EventEmitter()

em.$on('click', () => {console.log('click1')
})
em.$on('click', () => {console.log('click2')
})

em.$emit('click')

观察者模式

  • 观察者(订阅者)— Watcher

    • update():当事件产生时,具体要做的事件
  • 指标(发布者)— Dep

    • subs 数组:贮存所有观察者
    • addSub():增加观察者
    • notify():当事件产生时,调用所有观察者的 update() 办法
  • 没有事件核心

对于为什么指标(发布者)用 Dep 示意,是因为 Dep 是 dependence(依赖)的缩写。因为 Watcher 观察者(订阅者)须要依赖 Dep 能力理解数据的变动,没有 Dep,Watcher 基本不可能晓得数据产生了变动,当有数据变动产生时,Dep 会告诉 Watcher。

// 发布者 - 指标
class Dep {constructor () {
        // 记录所有的订阅者
        this.subs = []}
    
    // 增加订阅者
    addSub (sub) {
        // 在增加之前,要确保订阅者存在且具备 update 办法
        if (sub && sub.update) {this.subs.push(sub)
        }
    }
    
    // 公布告诉
    notify () {
        // 找到所有的订阅者并调用它们的 update 办法
        this.subs.forEach(sub => {sub.updatre()
        })
    }
}

// 订阅者 - 观察者
class Watcher {update () {console.log('update')
    }
}

let dep = new Dep()
let watcher = new Watcher()

dep.addSub(watcher)

dep.notify()

总结

  • 观察者模式 是由具体指标调度,比方当事件触发,Dep 就会去调用观察者的办法,所以观察者模式的订阅者和发布者之间是存在依赖的
  • 公布 / 订阅模式 由对立调度核心(事件核心)调用,因而发布者和订阅者不须要晓得对方的存在

事件核心隔离了发布者和订阅者,去除它们之间的相互依赖。观察者模式中,指标与观察者是相互依赖的,而公布订阅模式中,多了个事件核心。事件核心是隔离发布者和订阅者的,缩小发布者和订阅者的依赖关系,会变得更加灵便。

正文完
 0