什么是订阅和发布
发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。它可以使程序之前相互通信由不必彼此直接互相依赖
什么场景会用到订阅和发布
举个例子,当你在浏览一个新闻网站的时候,你可以订阅你感兴趣的博主,自此之后,每当博主发布了新的文章,都会给你推送他新发布的文章,(对于订阅者来说)你可以订阅多个博主;(对于发布者来说)博主也可具有多个订阅者
根据场景实现一个小demo
- 小明和小张都订阅了娱乐博主,当娱乐博主发送推送的时候,小张和小明都能收到消息
let starBlogger = {}
starBlogger.list = []
// on是订阅方法,将每个订阅者都放入list中
starBlogger.on = function (fn) {
this.list.push(fn)
}
// emit是发布方法,一旦触发emit,就会依次执行list里的函数
starBlogger.emit = function (data) {
this.list.forEach((cb) => {
cb(data)
})
}
// function (message){……},会被push进list中,等待有emit被触发时执行
// 小明订阅了明星专栏
starBlogger.on(function (message) {
console.log('小明订阅了明星专栏:' + message)
})
// 小张订阅了明星专栏
starBlogger.on(function (message) {
console.log('小张订阅了明星专栏:' + message)
})
// 明星专栏进行发布,触发emit
starBlogger.emit('XXX 结婚')
starBlogger.emit('YYY 公布恋情')
- 升级版!!!小明关注了娱乐博主,小张也关注了足球博主,两个博主分别对小张小明进行推送,互不干扰
let newsBlogger = {}
newsBlogger.list = []
// key代表了用户订阅的博主
newsBlogger.on = function (key, fn) {
if (!this.list[key]) {
this.list[key] = []
}
this.list[key].push(fn)
}
// 传入的key值代表要推送新闻的博主
newsBlogger.emit = function (key, data) {
// this.list[key]内存放的是订阅了该博主的所有用户,要对他们进行推送
let a = this.list[key]
if (a && a.length > 0) {
this.list[key].forEach((cb) => {
cb(data)
})
}
}
// 小明订阅娱乐博主
newsBlogger.on('娱乐博主', function (data) {
console.log('小明您好,您接受到一条来自娱乐博主的消息' + data)
})
// 小张订阅体育博主
newsBlogger.on('体育博主', function (data) {
console.log('小张您好,您收到一条来自体育博主的消息' + data)
})
// 博主开始推送
newsBlogger.emit('娱乐博主', '今日有新综艺更新')
newsBlogger.emit('体育博主', '今日巴萨进行主席竞选')
如何实现移除订阅
现在由于娱乐新闻过多,推荐过于频繁,小明不想关注娱乐博主了,他该如何取消订阅呢?
newsBlogger.remove = function (key, fn) {
var targerList = this.list[key]
if (targerList) {
for (let i = 0; i < targerList.length; i++) {
console.log(targerList[i])
console.log(fn)
if (targerList[i] = fn) {
targerList.splice(i, i + 1)
}
}
}
}
// 调用remove方法
newsBlogger.remove('娱乐博主', function (data) {
console.log('小明您好,您接受到一条来自娱乐博主的消息' + data)
})
其他使用场景
例如vue中的EventBus,其原理就是发布-订阅模式。 可以实现子组件像父组件传递信息。