基于ES6封装发布订阅模式

Posted captainmforlife

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于ES6封装发布订阅模式相关的知识,希望对你有一定的参考价值。

代码如下:  

封装自定义:subscribe.js

let _subscribe = (function () {
  // Sub 发布订阅类
  class Sub {
    constructor () {
      // 创建一个事件池 用来存储后期需要执行的方法
      this.$pond = [];
    }
    // 向事件池中追加方法(需要做去重处理)
    add (func) {
      let flag = this.$pond.some(item => {
        return item === func;
      });
      !flag ? this.$pond.push(func) : null;
    }
    // 从事件池中移出方法
    remove (func) {
      let $pond = this.$pond;
      for (let i = 0; i < $pond.length; i ++) {
        let item = $pond[i];
        if (item === func) {
          // 移出  (顺序不变的情况下只能用splice了)  但是不能这样写
          // 这样会导致数组塌陷,我们移出不能真移出,只能把当前项赋值为null
          // $pond.splice(i,1);
          $pond[i] = null;
          break;
        }
      }
    }
    // 通知事件池中的方法,按照顺序依次执行;
    fire (...args) {
      let $pond = this.$pond;
      for (let i = 0; i < $pond.length; i ++) {
        let item = $pond[i];
        if (typeof item !== ‘function‘) {
          // 此时再删除
          $pond.splice(i,1);
          i--;
          continue;
        }
        item.call(this,...args);
      }
    }
  }
  // 暴露给外面用
  return function subscribe () {
    return new Sub();
  }
})();
导入使用:
<div class="box" id="box" style="width: 100px; height: 100px; margin: 0 auto; background: seagreen;"></div>
<script>
   let pond = _subscribe();
  document.getElementById(‘box‘).onclick = function (ev) {
    pond.fire(ev);
  }
  let f1 = function () {
    console.log(1);
  }
  let f2 = function () {
    console.log(2);
    pond.remove(f1);
  }
  let f3 = function () {
    console.log(3);
  }
  let f4 = function (ev) {
    console.log(4,ev);
  }
  pond.add(f1);
  pond.add(f2);
  pond.add(f3);
  pond.add(f4);
</script>

以上是关于基于ES6封装发布订阅模式的主要内容,如果未能解决你的问题,请参考以下文章

用es6方式的写的订阅发布的模式

zeromq学习记录订阅发布消息封装

JS事件中的发布订阅模式

EventBus手写实现事件通信框架 ( 实现几个关键的封装类 | 消息中心 | 订阅注解 | 订阅方法封装 | 订阅对象-方法封装 | 线程模式 )

这是基于消息总线的发布-订阅模式吗?

RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用