浅谈发布订阅

181 阅读3分钟

老生长谈的发布订阅从中学习思路,理解他并结合自己的思考来去运用,变为自己的知识

前期思考

  • 怎么去订阅
  • 怎么去发布
  • 怎么去取消订阅
  • 怎么去定义PubSub类

我们在前期一定是围绕这几个点去思考代码逻辑

初步尝试

  1. 先定义一个PubSub
  2. 思考这个类里有什么? count(标记), events(存储回调的容器对象), publish(发布事件), subscribe(订阅事件), unSubscribe(取消订阅事件)
class PubSub{
	static count = 0;
     construct(){
       this.events = {}
     }
    subscribe(){}
    publish(){}
    unSubscribe(){}
}

到此为止我们的PubSub初步完成

完成 subscribe

思考subscribe函数的调用

//函数调用
PubSub.subscribe('事件类型',(数据)=>{})

//这里我们写个demo
PubSub.subscribe('pay',(data)=>{
  console.log('客户1号订阅', data)
})

PubSub.subscribe('pay',(data)=>{
  console.log('客户2号订阅', data)
})

PubSub.subscribe('pay',(data)=>{
  console.log('客户3号订阅', data)
})

//模仿有三个客户订阅pay类型

那此时我的Pubsub类中需要对相应的订阅做标记,以及缓存对应的回调

class PubSub{
	static count = 0;
     construct(){
       this.events = {}
     }
  //订阅
    subscribe(type,callack){
      //定义唯一的键防止key相同出现覆盖情况
      let token = type + '_' + PubSub.count
       this.events[token] = callBack //将回调缓存
      PubSub.count++
    }
  //发布 对所有的订阅者做一次广播
    publish(){
      
    }
  //取消订阅
    unSubscribe(){}
}

此时我们已经将所有订阅者的回调缓存到events对象中为什么我需要缓存这些回调呢?

发布订阅 publish

因为我需要我接下来发布时每一个订阅者都能感知,我们在js中在一个地方需要对代码另一个地方做数据传递,首先考虑函数,将数据一函数参数的形式进行传递,来做到数据分发

class PubSub{
	static count = 0;
     construct(){
       this.events = {}
     }
  //订阅
    subscribe(type,callack){
      //定义唯一的键防止key相同出现覆盖情况
      let token = type + '_' + PubSub.count
       this.events[type][token] = callBack //将回调缓存
      PubSub.count++
    }
  //发布 对所有的订阅者做一次广播
    publish(type,data){
      if(!this.events.hasOwnProperty(type)) return
     Object.values( this.events[type]).foreach((event)=>{
       event(data)
     })
    }
  //取消订阅
    unSubscribe(){}
}

//------------------------------------------

//调用
const myPubSub = new PubSub()

myPubSub.subscribe('pay',(data)=>{
  console.log('客户1号订阅', data)
})

myPubSub.subscribe('pay',(data)=>{
  console.log('客户2号订阅', data)
})

myPubSub.subscribe('pay',(data)=>{
  console.log('客户3号订阅', data)
})

myPubSub.publish('pay','我是广播的数据xxx')


此时检测到pay订阅事件的分发会依次调用缓存的回调对订阅者中对调函数的代码进行执行,这就是发布

取消订阅 unSubscribe

此时我们思考取消的三种操作

  • 当函数没有传参的时候
  • 当函数传入的参数是订阅类型的时候
  • 当函数传入的参数是subscribe的返回值时
class PubSub{
	static count = 0;
     construct(){
       this.events = {}
     }
  //订阅
    subscribe(type,callack){
      //定义唯一的键防止key相同出现覆盖情况
      let token = type + '_' + PubSub.count
       this.events[type][token] = callBack //将回调缓存
      PubSub.count++
    }
  //发布 对所有的订阅者做一次广播
    publish(type,data){
      if(!this.events.hasOwnProperty(type)) return
     Object.values( this.events[type]).foreach((event)=>{
       event(data)
     })
    }
  //取消订阅
    unSubscribe(params){
      if(!params){
        this.events = {}//清空缓存
      }else if(typeof params === 'string'){
       	if(!params.inCludes('_') ){
          	delete  this.events[params] 
         }else{
            let typeEvent = params.split("_")[0];
             delete this.events[typeEvent][params]
        }
      }
    }
}

//------------------------------------------

//调用
const myPubSub = new PubSub()

let hashMi =  myPubSub.subscribe('pay',(data)=>{
  console.log('客户1号订阅', data)
})

myPubSub.subscribe('pay',(data)=>{
  console.log('客户2号订阅', data)
})

myPubSub.subscribe('pay',(data)=>{
  console.log('客户3号订阅', data)
})

myPubSub.publish('pay','我是广播的数据xxx')

myPubSub.unSubscribe()
myPubSub.unSubscribe('pay')
myPubSub.unSubscribe(hashMi) 

这里需要对subscribe做返回值

    subscribe(type,callack){
      //定义唯一的键防止key相同出现覆盖情况
      let token = type + '_' + PubSub.count
       this.events[type][token] = callBack //将回调缓存
      PubSub.count++
      
      return token
    }

感谢!!!!!