返回

从观察者模式到手写EventEmitter源码:深入理解事件驱动编程

前端

从观察者模式到手写EventEmitter源码:深入理解事件驱动编程

前言

观察者模式是一种软件设计模式,它允许对象订阅另一个对象的事件,以便在该事件发生时采取行动。这种模式广泛应用于各种软件系统中,包括浏览器事件(如鼠标单击click,键盘事件keyDown)、GUI工具包和消息队列系统。

观察者模式的基本原理

观察者模式的核心思想是将观察者与被观察者分离。被观察者对象负责管理事件,而观察者对象负责订阅感兴趣的事件并采取相应的行动。这种分离可以提高系统的灵活性、可扩展性和松散耦合性。

观察者的角色

观察者的主要职责是订阅被观察者的事件并采取相应的行动。观察者可以是任何对象,只要它实现了观察者接口。观察者接口通常包含一个update()方法,该方法在被观察者状态发生变化时被调用。

被观察者的角色

被观察者的主要职责是管理事件和通知观察者。被观察者通常包含一个事件列表和一个用于添加和删除观察者的方法。当被观察者的状态发生变化时,它会通知所有已注册的观察者。

手写EventEmitter源码

为了更好地理解观察者模式,我们来手写一个简单的EventEmitter类。这个类将包含基本的事件管理功能,如添加和删除观察者,以及触发事件。

class EventEmitter {
  constructor() {
    this._events = {};
  }

  on(eventName, listener) {
    if (!this._events[eventName]) {
      this._events[eventName] = [];
    }
    this._events[eventName].push(listener);
  }

  removeListener(eventName, listener) {
    if (this._events[eventName]) {
      const index = this._events[eventName].indexOf(listener);
      if (index !== -1) {
        this._events[eventName].splice(index, 1);
      }
    }
  }

  emit(eventName, data) {
    if (this._events[eventName]) {
      this._events[eventName].forEach((listener) => {
        listener(data);
      });
    }
  }
}

实例代码

以下是一个使用EventEmitter类的简单实例:

const eventEmitter = new EventEmitter();

eventEmitter.on('click', () => {
  console.log('Button clicked!');
});

eventEmitter.emit('click');

当我们运行这段代码时,会在控制台中输出"Button clicked!"。这表明EventEmitter类可以正常工作。

结语

观察者模式是一种非常强大的设计模式,它可以用于各种软件系统中。通过手写EventEmitter源码,我们可以更好地理解观察者模式的基本原理和实现细节。