一、背景
发布订阅是一种程序的设计模式,看过很多篇相关文章,也看过不少源码中应用发布订阅的示例,但总是记不住,归根结底还是没有彻底掌握,现在结合生活中的实际场景来撸一遍代码,相信看完这篇文章,会对发布订阅有更深层次的理解,因为知识就是不断的日积月累,慢慢达到质的飞跃。
二、手写源码过程
1、我先拿最著名的卖楼事件举例。
小张、小王、小李都跟售楼部的小姐姐说了,等尾盘推出的时候给我打电话,小姐姐每次有新楼盘推出时都会挨个通知,小张迫于频繁被骚扰的压力,跟小姐姐说,等尾盘推出的时候你再通知我,其他楼盘开售就不用通知了,于是售楼部调整营销策略,整理了一份花名册,如下:
对A楼有意向的客户:小张(17600697799)、小王(17600697791)
对B楼有意向的客户:小李(17600697792)、小赵(17600697793)
对C楼有意向的客户:小马(17600697794)、小刘(17600697795)
2、映射到发布订阅中
class PublishSubscribe {
constructor () {
this.subscribes = {} // 存储所有的订阅函数
// subscribes = {
// A: [cb1,cb2,cb3], 订阅A楼的用户
// B: [cb4, cb5] 订阅B楼的用户
// }
}
// 订阅过程:把订阅函数存起来
on(key, callback) {
if (!this.subscribes[key]) {
this.subscribes[key] = []
}
this.subscribes[key].push(callback)
}
// 发布过程,例如A楼开售时,需要找出订阅A楼的用户,挨个通知
emit(key, ...args) {
const subscribeCallbacks = this.subscribes[key]
for (let i=0;i<subscribeCallbacks.length;i++) {
subscribeCallbacks[i].call(this, ...args)
}
}
}
const publish = new PublishSubscribe()
publish.on('A', (price, square) => {
console.log(`A号楼,价格是${price}, 面积是${square}`)
})
publish.on('B', (price, square) => {
console.log(`B号楼,价格是${price}, 面积是${square}`)
})
publish.emit('A', 7000, 88)
publish.emit('B', 10000, 105)