ts-17发布订阅模式

37 阅读1分钟

什么是发布订阅模式?

  • 当订阅的事件被触发时,订阅事件的对象都会收到通知

  • 举例

    • 比如你去买奶茶,下单的时候会根据点餐系统就行排号,然后你可以去座位那等着。
    • 奶茶好了之后,工作人员会点击奶茶制作完成通知顾客,点餐系统就会通知你发送到手机提醒你来取
  • 比如

    • js中的 addEventListener
    • vue中的 eventBus

image.png

例子

  •   interface Face {
        on: (name: string, fn: Function) => void
        emit: (name: string, ...args: Array<any>) => void
        off: (name: string, fn: Function) => void
        once: (name: string, fn: Function) => void
      }
    
      interface Arr {
        [key: string]: Array<Function>
      }
    
      class Dispath implements Face {
        arr: Arr
        constructor() {
          this.arr = {}
        }
    
        on(name: string, fn: Function) {
          const callback = this.arr[name] || []
          callback.push(fn)
          this.arr[name] = callback
          // console.log(this.arr) // { post: [ [Function (anonymous)] ] }
        }
    
        emit(name: string, ...args: Array<any>) {
          let eventName = this.arr[name]
          if (eventName) {
            eventName.forEach(fn => {
              fn.apply(this, args)
            })
          } else {
            console.error(`名字错了${name}`)
          }
        }
    
        off(name: string, fn: Function) {
          let eventName = this.arr[name]
          if (eventName && fn) {
            let index = eventName.findIndex(i => i === fn)
            eventName.splice(index)
          } else {
            console.error(`名字错了${name}`)
          }
        }
    
        once(name: string, fn: Function) {
          let fake = (...args: Array<any>) => {
            fn.apply(this, args)
            this.off(name, fake)
          }
          this.on(name, fake)
        }
      }
    
      const d = new Dispath()
    
      d.on('ys', (...args: Array<any>) => {
        console.log('on', args)
      })
    
      // d.once('ys', (...args: Array<any>) => {
      //   console.log('once', args)
      // })
    
      const fn4 = (...args: Array<any>) => {
        console.log('ys', args)
      }
    
      // d.off('ys', fn4)
    
      // d.on('ys', fn4)
    
      d.emit('ys', '亚索', { name: '亚索', age: 12 })
    
      // d.emit('ys', '瑞雯', { name: '瑞雯', age: 20 })