发布、订阅模式

发布订阅,根据我自己的理解:

  • 首先有一个收集订阅的东西,然后有订阅者
  • 收集订阅主要有三部分:1.存储订阅的数组 2.添加订阅者到订阅数组中的方法 3.发布订阅的方法
  • 其中上述发布订阅的方法也就是根据所有订阅者的信息,来对每个订阅者通知进行的变化。
  • 订阅者有两部分:1.订阅者的回调函数 2.触发回调函数的方法
  • 创建一个订阅者实例一定要创建这个回调函数,那么这个回调函数的作用是什么呢?
  • 这个回调函数就是根据最新的数据来重新更新自己的内容的一个方法函数
//收集订阅
class Dep {
    constructor() {
        //subs数组,用来存放所有订阅者的信息
        this.subs = []
    }

    //向subs数组中添加订阅信息
    addSub(watcher) {
        this.subs.push(watcher)
    }

    //发布订阅的方法(循环subs数组,调用每个订阅者的订阅信息)
    notify() {
        this.subs.forEach(watcher => watcher.update())
    }
}


//订阅者的类
class Watcher {
    //cb代表回调函数,将回调函数挂载到自己身上
    //注意其中cb代表传入的一个函数
    constructor(cb) {
        this.cb = cb
    }

    //触发回调的方法
    update() {
        this.cb()
    }
}

//创建订阅者以及其要实现的东西
const w1 = new Watcher(() => {
    console.log('我是第1个订阅者') //这个在实际运用是实现更新自己的函数
})

const w2 = new Watcher(() => {
    console.log('我是第2个订阅者') //如何根据最新的数据来更新自己的函数
})

const dep = new Dep()
    //将订阅者加到收集订阅的数组中
dep.addSub(w1)
dep.addSub(w2)
    //将收集到的订阅按照顺序依次发布出去,也就是实现订阅
dep.notify()

输出:
我是第1个订阅者
我是第2个订阅者

//在Vue中为什么需要这个发布订阅的操作呢?
//因为在监测到某个数据变化后,需要通知每个订阅者,我这个数据发生变化了
//那么每个订阅者就会根据这个已经变化的数据,重新渲染自己的dom节点

//即dep.notify()的作用
//只要我们为Vue中data数据重新赋值了,这个赋值动作就会被Vue监听到。
//然后Vue要把数据的变化,通知到每个订阅者。
//接下来,订阅者(Dom元素)要根据最新的数据,更新自己的内容

手写一个发布订阅

// 发布订阅中心, on-订阅, off取消订阅, emit发布, 内部需要一个单独事件中心caches进行存储;
interface CacheProps {
  [key: string]: Array<((data?: unknown) => void)>;
}

class Observer {
  private caches: CacheProps = {}; // 事件中心
  on (eventName: string, fn: (data?: unknown) => void){ // eventName事件名-独一无二, fn订阅后执行的自定义行为
    this.caches[eventName] = this.caches[eventName] || [];
    this.caches[eventName].push(fn);
  }

  emit (eventName: string, data?: unknown) { // 发布 => 将订阅的事件进行统一执行
    if (this.caches[eventName]) {
      this.caches[eventName].forEach((fn: (data?: unknown) => void) => fn(data));
    }
  }

  off (eventName: string, fn?: (data?: unknown) => void) { // 取消订阅 => 若fn不传, 直接取消该事件所有订阅信息
    if (this.caches[eventName]) {
      const newCaches = fn ? this.caches[eventName].filter(e => e !== fn) : [];
      this.caches[eventName] = newCaches;
    }
  }

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值