订阅和发布最常见的就是公众号了,关注公众号就是订阅,公众号新文章推送就是发布。细化到代码层面,订阅就是相当创建了一个键值对为
xxx: fn的对象,当需要发布时,调用fn就可以。
1、声明一个对象
const eventHub = {
map:{
// click:[f1,f2] // 每多一人订阅,index + 1。
},
// 订阅
on:(name,fn)=>{
eventHub.map[name]=[] || eventHub.map[name]
eventHub.map[name].push(fn)
}
// 取消订阅
off:(name,fn)=>{
const value = eventHub.map[name]
if(!value) return
const index = value.indexOf(fn)
if(index<0) return
value.splice(index,1)
}
// 发布(新数据)
emit:(name,data)=>{
const value = eventHub.map[name]
if(!value) return
value.map(f=>f(data)) // 依次向每个订阅者发布
}
}
// 使用
eventHub.on('click', value => console.log('我是第一个订阅者;' + value))
eventHub.on('click', value => console.log('我是第二个订阅者;' + value))
setTimeout(eventHub.emit('click', '数据已更新'), 3000)
eventHub.off('click', value => console.log('我是第二个订阅者;' + value))
2、使用类实现发布订阅
class EventHub = {
map = {}
on(name,fn)=>{
this.map[name]=[] || this.map[name]
this.map[name].push(fn)
}
off(name,fn)=>{
const value = this.map[name]
if(!value) return
const index = value.indexOf(fn)
if(index<0) return
value.splice(index,1)
}
emit(name,data)=>{
const value = this.map[name]
if(!value) return
value.forEach(f=>f(data))
}
}
// 使用
const e = new EventHub()
e.on('click', value => console.log('我是第一个订阅者;' + value))
e.on('click', value => console.log('我是第二个订阅者;' + value))
setTimeout(e.emit('click', '数据已更新'), 3000)
e.off('click', value => console.log('我是第二个订阅者;' + value))