观察者模式 & 发布-订阅模式(设计模式与开发实践 P8)

文章目录

观察者模式

定义:他用来定义对象之间一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖他的对象都会得到通知

运用

如果我们使用过 DOM 上的事件函数,那就接触过观察者模式

javascript 复制代码
document.body.addEventListener(
  "click",
  function () {
    console.log("body clicked");
  },
  false
);

document.body.click(); // 输出:body clicked

这段代码中 body 上添加了一个订阅者,而 document.body.click() 向所有订阅者发送了点击事件~

我们可以随意添加 订阅者 而不会影响 发布者 代码的编写

实现

接下来尝试实现一些自定义事件,通过 listen 监听某个名为 key 的事件,通过 trigger 执行事件回调函数

javascript 复制代码
var saleOffices = {
  clientList: [], // 缓存列表,存放订阅者的回调函数
  listen: function (key, fn) {
    // 增加订阅者
    if (!this.clientList[key]) {
      // 如果还没有订阅过此类消息,给该类消息创建一个缓存列表
      this.clientList[key] = []; // 直接把函数推入数组
    }
    this.clientList[key].push(fn); // 订阅的消息添加进缓存列表
  },
  trigger: function () {
    // 发布消息
    var key = Array.prototype.shift.call(arguments); // 取出消息类型
    var fns = this.clientList[key]; // 取出该消息对应的回调函数集合
    if (!fns || fns.length === 0) {
      // 如果没有订阅该消息,则返回
      return false;
    }
    for (var i = 0, fn; (fn = fns[i++]); ) {
      // 依次执行订阅的回调函数
      fn.apply(this, arguments); // arguments 是发布消息时带上的参数
    }
  },
};

// ----- 测试 -----
saleOffices.listen("squareMeter88", function (price) {
  // 小明订阅消息
  console.log("小明得到价格= " + price);
});

saleOffices.listen("squareMeter100", function (price) {
  // 小红订阅消息
  console.log("小红价格= " + price);
});

saleOffices.trigger("squareMeter88", 2000000); // 输出:2000000
相关推荐
还是大剑师兰特1 分钟前
Vue3 + Element Plus 日期选择器:开始 / 结束时间,结束时间不超过今天
前端·javascript·vue.js
不会写DN1 分钟前
Js常用数组处理
开发语言·javascript·ecmascript
还是大剑师兰特3 分钟前
数组中有两个数据,将其变成字符串
开发语言·javascript·vue.js
Saga Two4 分钟前
Vue实现核心原理
前端·javascript·vue.js
技术钱4 分钟前
vue3实现时间根据系统时区转换对应的时间
javascript·vue.js
殷忆枫11 分钟前
基于STM32的ML307R连接Onenet平台
服务器·前端·javascript
Java 码农12 分钟前
vue cli 环境搭建
前端·javascript·vue.js
酉鬼女又兒17 分钟前
零基础入门前端JavaScript Object 对象完全指南:从基础到进阶(可用于备赛蓝桥杯Web应用开发赛道)
开发语言·前端·javascript·职场和发展·蓝桥杯
RPGMZ20 分钟前
RPGMakerMZ游戏引擎 地图角色顶部显示称号
javascript·游戏引擎·rpgmz·rpgmakermz
wuhen_n24 分钟前
异步组件与 Suspense:如何优雅地处理加载状态并优化首屏加载?
前端·javascript·vue.js