手写发布订阅

99 阅读1分钟
class EventEmitter {
  eventList = [];
  // 订阅事件
  on(event, fn) {
    (this.eventList[event] || (this.eventList[event] = [])).push(fn);
  }
  // 订阅一次事件
  once(event, fn) {
    function one() {
      // arguments是数组 所以要用apply
      fn.apply(this, arguments);
      this.off(event, one);
    }
    this.on(event, one);
  }
  // 发布关于事件的消息
  emit(event, data) {
    if (!this.eventList[event]) return false;
    this.eventList[event].forEach((fn) => {
      fn.call(this, data);
    });
  }
  // 取消订阅
  off(event, fn) {
    if (!this.eventList[event]) return;
    if (!fn) {
      this.eventList[event] = [];
    } else {
      this.eventList[event] = this.eventList[event].filter((itm) => itm !== fn);
    }
  }
}

function user1(content) {
  console.log("用户1订阅了:", content);
}

function user2(content) {
  console.log("用户2订阅了:", content);
}

function user3(content) {
  console.log("用户3订阅了:", content);
}

function user4(content) {
  console.log("用户4订阅了:", content);
}

let eventEmitter = new EventEmitter();

// 订阅
eventEmitter.on("article1", user1);
eventEmitter.on("article1", user2);
eventEmitter.on("article1", user3);

// 取消user2方法的订阅
eventEmitter.off("article1", user2);

eventEmitter.once("article2", user4);

// 发布
eventEmitter.emit("article1", "Javascript 发布-订阅模式");
eventEmitter.emit("article1", "Javascript 发布-订阅模式");
eventEmitter.emit("article2", "Javascript 观察者模式");
eventEmitter.emit("article2", "Javascript 观察者模式");
eventEmitter.emit("article2", "Javascript 观察者模式");