美文网首页
手写一个简单的事件订阅发布模式

手写一个简单的事件订阅发布模式

作者: 转移到CSDN名字丹丹的小跟班 | 来源:发表于2021-03-11 08:59 被阅读0次
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>订阅发布</title>
  </head>
  <body>
    <script>
      // 创建一个构造函数
      function Public() {
        //给实例创建一个handlers属性
        this.handlers = {};
      }
      // 给类的原型绑定对象事件
      Public.prototype = {
        // 创建constructor属性指向原构造函数
        constructor: Public,
        // 订阅事件
        on(eventType, handler) {
          // 首先判断是否存在此私有属性(也就是事件类型),若有,则直接push到原有数组里面,若没有,则定义一个空数组储存函数
          if (!this.handlers.hasOwnProperty(eventType)) {
            this.handlers[eventType] = [];
          }
          this.handlers[eventType].push(handler);
          // 返回实例,从而可以进行链式写法(以下return this含义相同)
          return this;
        },
        // 触发事件(发布事件)
        emit(eventType) {
          // 将传递过来的参数从位置1截取到末尾,并返回一个数组。
          let handlerArgs = Array.prototype.slice.call(arguments, 1);
          //遍历这个私有属性(也就是事件类型)的数组里面存储的函数,并将它们执行。
          for (let i = 0; i < this.handlers[eventType].length; i++) {
            this.handlers[eventType][i].apply(this, handlerArgs);
          }
          return this;
        },
        // 删除订阅事件
        off(eventType, handler) {
          // 取出当前事件类型
          let currentEvent = this.handlers[eventType];
          let len = 0;
          // 判断事件是否存在
          if (currentEvent) {
            // 取出存储的函数个数
            len = currentEvent.length;
            // 避免数组塌陷,从后往前遍历删除
            for (let i = len - 1; i >= 0; i--) {
              if (currentEvent[i] === handler) {
                currentEvent.splice(i, 1);
                console.log("删除订阅事件成功!");
              }
            }
          }
          return this;
        },
      };

      let Publisher = new Public();
      function test1(data) {
        console.log('test1' + data);
      }
      function test2(data) {
        console.log('test2' + data);
      }
      //订阅事件test
      Publisher.on("test", test1);
      Publisher.on("test", test2);
      //触发事件test
      Publisher.emit("test", "我是第1次调用的参数").emit("test","我是第2次调用的参数"); //链式调用
      Publisher.emit("test", "我是第1次调用的参数"); //直接调用
      Publisher.emit("test", "我是第2次调用的参数"); //直接调用
      // 删除订阅事件test
      Publisher.off("test", test2);
      Publisher.emit("test", "已经被删除,test1不会再触发");
      //  1我是第1次调用的参数
      //  2我是第1次调用的参数
      //  1我是第2次调用的参数
      //  2我是第2次调用的参数
    </script>
  </body>
</html>

相关文章

  • 手写一个简单的事件订阅发布模式

  • 使用Typescript手写一个Eventhub(发布订阅模式)

    什么是发布-订阅模式? 发布-订阅模式主要包含三个模块, 发布者,事件处理中心,订阅者。举个简单的例子,假设我们是...

  • 异步编程解决方案

    事件发布/订阅模式 事件监听器模式是一种广泛用于异步编程的模式,是回调函数的事件化,又称发布/订阅模式。 事件发布...

  • 发布订阅模式和观察者模式

    发布/订阅模式 订阅者 发布者 事件中心 我们假定,存在一个“事件中心”,某个任务执行完成,就向事件中心“发布”(...

  • 如何手写一个简单发布订阅模式

    面试过程中很多面试官如何手写个发布订阅模式下面就是一个简单的demo

  • 常见设计模式

    问答 写出构造函数模式、混合模式、模块模式、工厂模式、单例模式、发布订阅模式的范例。 使用发布订阅模式写一个事件管...

  • 如何理解js的发布-订阅模式

    发布-订阅模式/观察者模式 发布-订阅模式也叫观察者模式,这是一个一对多的关系,可以多个订阅者订阅同一个事件,当事...

  • js 普通for循环的各种写法

    lio-mengxiang分享的面试题,手写一个基于发布订阅模式的事件绑定机制 上面的循环没有递增条件,引发思考,...

  • 常见设计模式

    写出 构造函数模式、混合模式、模块模式、工厂模式、单例模式、发布订阅模式的范例。 使用发布订阅模式写一个事件管理器...

  • 前端设计模式

    写出 构造函数模式、混合模式、模块模式、工厂模式、单例模式、发布订阅模式的范例。 使用发布订阅模式写一个事件管理器...

网友评论

      本文标题:手写一个简单的事件订阅发布模式

      本文链接:https://www.haomeiwen.com/subject/sroofltx.html