定义
发布-订阅模式:又称为观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态改变时,所有依赖于它的对象都将得到通知。
这个有点类似于我们平时关注的公众号,公众号发布消息,所有订阅了的人,都会收到消息。
实现一个简单的发布订阅模式
const Event = function () {
this.obj = {}
}
Event.prototype.on = function (eventType, fn) {
if (!this.obj[eventType]) {
this.obj[eventType] = []
}
this.obj[eventType].push(fn)
}
Event.prototype.emit = function () {
const eventType = Array.prototype.shift.call(arguments)
const arr = this.obj[eventType]
for (let i = 0; i < arr.length; i++) {
arr[i].apply(arr[i], arguments)
}
}
const ob = new Event()
ob.on('say', function (msg) { // 订阅
console.log(msg) // hello
})
ob.emit('say', 'hello') // 发布
当我们将原本emit里触发的函数缓存下来,放到on中触发,就可以实现先发布函,后订阅。就像下面这样。
const Event = function () {
this.obj = {}
this.cacheList = []
}
Event.prototype.on = function (eventType, fn) {
if (!this.obj[eventType]) {
this.obj[eventType] = []
}
this.obj[eventType].push(fn)
for (let i = 0; i < this.cacheList.length; i++) {
// 订阅时,执行之前发布时,缓存下来的 cache
this.cacheList[i]()
}
}
Event.prototype.emit = function () {
const arg = arguments
const that = this
function cache() {
var eventType = Array.prototype.shift.call(arg)
var arr = that.obj[eventType]
for (let i = 0; i < arr.length; i++) {
arr[i].apply(arr[i], arg)
}
}
// 发布时,将 cache 缓存下来
this.cacheList.push(cache)
}
const ob = new Event()
ob.emit('say', 'hello')
ob.on('say', function (msg) {
console.log(msg) // hello
})
总结
发布订阅模式主要的好处就是对象之间的解耦,帮助我们写出更松耦合的代码。缺点是订阅者的创建是消耗一定的时间和内存的。使用过多也是难以维护的。