首页 > 其他 > 详细

观察者模式与简单实现

时间:2020-09-22 09:17:30      阅读:59      评论:0      收藏:0      [点我收藏+]

观察者模式与简单实现

本文写于 2020 年 9 月 22 日

观察者模式(Observer Pattern)是一种设计模式,也可以叫做「发布-订阅模式」。

他就像你订了一本杂志,每当杂志新刊发布的时候,所有订阅过杂志的人都会收到新刊一样。

观察者模式定义了对象之间一种 一对多 的依赖关系,每当该对象的状态发生改变的时候,所依赖于它的其他对象都将得到通知。

在 JavaScript 中,我们会经常接触到一个很类似的东西——事件。

事件与观察者模式

我们先为一个 #app 元素添加两个点击事件:

document.querySelector(‘#app‘).addEventListener(‘click‘, () => {
  // 事件 1
});
document.querySelector(‘#app‘).addEventListener(‘click‘, () => {
  // 事件 2
});

这个时候,我们点击 #app 元素或者使用 document.querySelector(‘#app‘).click() 或者 document.querySelector(‘#app‘).dispatchEvent(‘click‘) 来触发时,这两个事件都会被触发——是不是类似与很多对象依赖于一个对象,该对象改变后所有依赖者都会被触发。

自定义「发布-订阅」

我们来自定义一个事件来试试。

首先我们需要一个数组储存所有的触发函数,这样我们就可以对其进行遍历,后触发每一个事件。

const children = [];

我们还需要一个方法,来对 children 数组进行 push

const listen = (fn) => {
  children.push(fn);
}

我们再增加一个触发函数 trigger,让它去遍历并触发我们的 children

const trigger = () => {
  children.forEach((child) => {
    child();
  })
}

OK,接下来我们整合一下:

class eventHub {
  children = {}

  listen(key, fn) {
    if(this.children[key]) {
      this.children[key].push(fn);
    } else {
      this.children[key] = [fn]
    }
  }

  trigger(key) {
    this.children[key]?.forEach((child) => {
      child();
    });
  }

  remove(key, fn) {
    if(this.children[key]) {
      const children =this.children[key]
      const target = children.indexOf(fn)
      this.children[key] = [...children.slice(0, target), ...children.slice(target + 1)]
    }
  }
}

这里我们将数组换成了对象,并且为函数增加了参数,因为我们希望够可以对多个事件进行监听。

还添加了一个移除事件——所以我们最好使用具名函数,如果是匿名函数就无法移除监听了!

有哪些例子?

例如一个电商网站的登陆系统,需要获取用户基础信息后,获取用户的各项历史记录:

function onLogin() {
  getUserInfo()
    .then(() => {
      return getUserHistory()
    })
    .then(() => {
      getUserXXX()
    })
}

那么一旦我们需要新增一个功能,就需要在这个长函数中增加新项。

如果使用了发布-订阅模式,就可以非常简单的写上新的、独立的事件监听了。

(完)

观察者模式与简单实现

原文:https://www.cnblogs.com/xhyccc/p/13710065.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!