发布订阅者模式解析

217 阅读1分钟

发布订阅者模式是面试中常见的问题之一, 以下是本人写的, 供大家参考, 如果有误多多留言哈...

    const event = {
      list: {},
      onceList: {},
      // 将键和键对应的回调存储在对象中
      $emit(key, fn) {
        if (!this.list[key]) {
          this.list[key] = [];
        }
        this.list[key].push(fn);
      },
      // 根据键名对应的回调依次执行
      $on() {
        const type = Array.prototype.shift.apply(arguments);
        const fns = this.list[type];
        const onceFn = this.onceList[type];
        if (onceFn) {
          onceFn.apply(this, arguments);
          delete onceFn;
        }
        if (fns) {
          for (var i = 0; i < fns.length; i++) {
            fns[i].apply(this, arguments);
          }
        }
      },
      // 意义: 只能触发首次添加的回调
      $once(key, fn) {
        this.onceList[key] = fn;
      },
      // 找到键对应的回调集合, 删掉集合中对应的回调函数
      $remove(key, fn) {
        const list = this.list[key];
        const onceList = this.onceList[key];
        if (onceList) {
          delete oncelist;
        }
        if (!list) {
          return false;
        }
        if (!fn) {
          list && (list.length = 0);
        } else {
          for (var i = 0; i < list.length; i++) {
            if (list[i] === fn) {
              list.splite(i, 1);
            }
          }
        }
      }
    };

    event.$emit("jojo", function() {
      console.log(32);
    });
    event.$emit("jojo", function() {
      console.log(33);
    });
    event.$once("xiaoming", function() {
      console.log(888);
    });
    event.$once("xiaoming", function() {
      console.log(999);
    });
    event.$on("jojo");
    event.$on("xiaoming");
``