EventEmitter简单实现

最近重新注意到node是由事件驱动的,所以主要看了下官网的EventEmitter,发现貌似实现起来很简单,于是简单重写了下,只是实现了几个比较重要的方法


class MyEmitter {
  constructor() {
    this.eventsMap = {};
  }

  on(event, callback) {
    if (typeof callback !== "function") throw new Error("传函数");
    this.eventsMap[event] = {
      isOnce: false,
      callback,
    };
  }

  emit(event, ...args) {
    const { isOnce, callback } = this.eventsMap[event] || {};
    if (isOnce) delete this.eventsMap[event];

    try {
      callback.apply(this, args);
    } catch (error) {
      const { callback: errorHandler } = this.eventsMap["error"] || {};
      if (!errorHandler) throw new Error(error);
      errorHandler.call(this, error);
    }
  }

  once(event, callback) {
    if (typeof callback !== "function") throw new Error("传函数");
    this.eventsMap[event] = {
      isOnce: true,
      callback,
    };
  }
}

测试案例:


const myEmitter = new MyEmitter();

myEmitter.on("work", () => {
  console.log("work daily");
});

myEmitter.on("play", function (thing, someone) {
  console.log(`i am playing ${thing} with ${someone}`);
  console.log(this);
});

myEmitter.on("error", function (error) {
  console.log(`${Date.now()} - ${error.message}`);
});

let count = 0;
myEmitter.once("add", function (thing, someone) {
  console.log(++count);
});

//同步执行
myEmitter.emit("work");
myEmitter.emit("work");

myEmitter.emit("play", "basktball", "cxk");

myEmitter.emit("add");
myEmitter.emit("add");

跑出来的结果如下:

work daily
work daily
i am playing basktball with cxk
MyEmitter {
  eventsMap: {
    work: { isOnce: false, callback: [Function] },
    play: { isOnce: false, callback: [Function] },
    error: { isOnce: false, callback: [Function] },
    add: { isOnce: true, callback: [Function] }
  }
}
1
1635074408913 - Cannot read property 'apply' of undefined

你可能感兴趣的:(EventEmitter简单实现)