使用可观察对象,在事件发生的时候通知订阅者

说明

观察者模式,可以将某些对象(观察者)订阅到另一个对象,称为可观察对象

每当事件发生时,可观察对象都会通知所有观察者!也就是一旦可观察对象发生变化,所有的观察者都会得到通知

  • 观察者:可以类比为很多人在看某一个东西,当这个东西发生变化的时候,观察者都能够感觉到对应的变化
  • 可观察对象:能够通知观察者的一个可变对象

概念

有了上述的说明,那我们便可以实现这样一个模式,首先这个模式中,需要添加几个概念

  1. observers:存放一系列的观察者
  2. subscribe:一个可以将观察者放入observers的方法
  3. unsubscribe:将观察者移出observers
  4. notify:当某个事件发生时,通知观察者

实现

有了上述的概念,我们来实现一下

class Observable {
  constructor() {
    this.observers = [];
  }

  subscribe(func) {
    this.observers.push(func);
  }

  unsubscribe(func) {
    this.observers = this.observers.filter(observer => observer !== func);
  }

  notify(data) {
    this.observers.forEach(observer => observer(data));
  }
}

应用

目前我们已经实现了观察者模式,是不是很简单,那具体的能够用在什么地方呢?

假设这么一个例子,我们点击页面上某一个按钮的时候,需要执行很多操作,比如记录日志,弹出窗口,提交信息,切换按钮等等

很多时候我们会将这些方法写在一个handle函数中进行处理,当然这没有什么问题,但是如果你用观察者模式的话,你的代码逻辑会变的更精简和清晰,当然上述的逻辑都比较简单,但是在业务逻辑中,这些内容会变的很复杂

流程主要如下

也就是每当用户执行handleClick操作的时候,就会触发notify方法,notify通知所有的观察者,这里的观察者就是所有待执行的方法

实际代码如下

我们先创建观察者,上面我们提到了一系列的观察者,我们用伪代码实现

function logger(data){
  console.log(Data.now + data)
}

function alerter(data){
  alert(Data.now + data)
}

function submitData(data){
  submit(data)
}

function changeSwitch(data){
  change(data ? true : false)
}

虽然有了这些观察者,但是我们需要将这些添加到observers,按照前面所实现的内容,我们需要调用subscribe方法

const observable = new Observable()
observable.subscribe(logger)
observable.subscribe(alerter)
observable.subscribe(submitData)
observable.subscribe(changeSwitch)
// 当然你可以优化subscribe传一个数组进去,就不用调用这么多次了

现在观察者已经准备就绪,然后我们需要实现通知方法,因为handleClick在点击的时候,就可以去做对应的通知,并传递数据,所以我们可以这样

function handleClick1(){
  observable.notify('message')
}

现在我们就完成了整个发布订阅的流程

总结

当然这仅仅只是一个例子,点击事件对于我们来说其实也是异步的,针对这一点,很容易的就能想到其实观察者模式在处理异步逻辑的时候非常有用。比如等待接口回来之后我们处理一些任务,或者得到一些通知

又或者你希望某些组件在某些数据下载完成的时候得到通知,或者有用户向留言板发送消息的时候通知其他人都可以使用这种方式

当然这种模式最大的好处就是在团队开发中,尤其是那种大型的项目中,一个开发者很难做到熟悉项目中的各种模块,如果此时为了完成某个多模块的需求,这个观察者模式优势就出来了,模块间的信息传递不必引入其他模块,只需要通过观察者模式进行注册或者发布消息,这种模式可以在开发自己模块的时候隔离其他模块,防止对其他业务逻辑造成影响

参考https://www.patterns.dev/post...

FE情报局
30 声望5 粉丝