秋雨
首页
  • HTML
  • CSS
  • JavaScript
设计模式
webpack
  • 前端常识
  • ES
  • React
  • Redux
  • ReactRouter
  • 事件循环
  • 浏览器渲染流程
  • Vue项目性能优化
  • Vue
  • App
Github
首页
  • HTML
  • CSS
  • JavaScript
设计模式
webpack
  • 前端常识
  • ES
  • React
  • Redux
  • ReactRouter
  • 事件循环
  • 浏览器渲染流程
  • Vue项目性能优化
  • Vue
  • App
Github
  • 构造器模式
  • 原型链模式
  • 工厂模式
  • 抽象工厂模式
  • 建造者模式
  • 单例模式
  • 装饰器模式
  • 适配器模式
  • 适配器模式
  • 代理模式
  • 观察者模式
  • 发布订阅模式
  • 模块模式
  • 桥接模式
  • 组合模式
  • 命令模式
  • 命令模式
  • 迭代器模式
  • 职责链模式

简介

观察者和目标要相互知道 发布者和订阅者不用互相知道,通过第三方实现调度,属于经过解耦合的观察者模式。

const PubSub = {
  list: [],
  publish() {
    this.list.forEach((item) => item());
  },
  subscribe(cb) {
    this.list.push(cb);
  },
};

function testA() {
  console.log("testA");
}

function testB() {
  console.log("testB");
}

PubSub.subscribe(testA);
PubSub.subscribe(testB);

PubSub.publish();

示例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发布订阅模式</title>
  </head>
  <body>
    <script>
      /*
          1. 观察者和目标要相互知道
          2. 发布者和订阅者不用互相知道,通过第三方实现调度,属于经过解耦合的观察者模式。
          */

      const PubSub = {
        message: {},
        publish(type, data) {
          // this.list.forEach((item) => item());
          if (this.message[type]) {
            return;
          }
          this.message[type].forEach((element) => {
            item(data);
          });
        },
        subscribe(type, cb) {
          if (!this.message[type]) {
            this.message[type] = [cb];
          } else {
            this.message[type].push(cb);
          }
        },
        unsubscribe(type, cb) {
          if (!this.message[type]) return;
          if (cb) {
            //取消所有
            this.message[type] && (this.message[type].length = 0);
          } else {
            this.message[type] = this.message[type].filter(
              (item) => item !== cb
            );
          }
        },
      };

      function testA(data) {
        console.log("testA", data);
      }
      function testB() {
        console.log("testB", data);
      }

      function testC() {
        console.log("testC", data);
      }

      PubSub.subscribe("A", testA);
      PubSub.subscribe("A", testA);
      PubSub.subscribe("B", testB);
      // PubSub.subscribe(testB);

      // PubSub.publish();
    </script>
  </body>
</html>

示例 2

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发布订阅</title>
    <style>
      .box {
        display: flex;
        height: 500px;
      }
      .box .left {
        width: 150px;
        background-color: skyblue;
      }
      .box .right {
        flex: 1;
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <header class="header">路径</header>
    <div class="box">
      <div class="left">
        <ul>
          <li>首页</li>
          <li>用户管理</li>
          <li>权限管理</li>
          <li>新闻管理</li>
        </ul>
      </div>
      <div class="right">
        <div class="bread"></div>
      </div>
    </div>

    <script>
      const PubSub = {
        message: {},
        publish(type, data) {
          // this.list.forEach((item) => item());
          if (this.message[type]) {
            return;
          }
          this.message[type].forEach((element) => {
            item(data);
          });
        },
        subscribe(type, cb) {
          if (!this.message[type]) {
            this.message[type] = [cb];
          } else {
            this.message[type].push(cb);
          }
        },
        unsubscribe(type, cb) {
          if (!this.message[type]) return;
          if (cb) {
            //取消所有
            this.message[type] && (this.message[type].length = 0);
          } else {
            this.message[type] = this.message[type].filter(
              (item) => item !== cb
            );
          }
        },
      };

      PubSub.subscribe("UpdateBread", function (data) {
        console.log("我是订阅者", data);
        document.querySelector(".bread").innerHTML = data;
      });
      let oli = document.querySelectorAll(".left li");
      for (let i = 0; i < oli.length; i++) {
        oli[i].onclick = function () {
          console.log(this.innerHTML);
          PubSub.publish("UpdateBread", this.innerHTML);
        };
      }
    </script>
  </body>
</html>
最后更新:
贡献者: Mrlishizhen
Prev
观察者模式
Next
模块模式