返回

发布订阅模式探索:揭秘Node.js EventEmitter源码

前端

前言

在上一篇《setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop》中,我们详细探讨了浏览器和Node.js的异步API及其底层原理Event Loop。而本文,将揭秘一种无需借助原生API即可实现异步效果的强大模式——发布订阅模式。发布订阅模式是面试中的热门话题,掌握它将为您的技术面试之路增添筹码。

发布订阅模式的魅力与应用

发布订阅模式,又称观察者模式,是一种强大的设计模式,它允许对象之间进行松耦合的通信。在该模式中,发布者对象将发布事件,而订阅者对象则监听这些事件并作出相应的反应。这种模式广泛应用于各种场景,如事件处理、消息传递、UI更新等等。

Node.js的EventEmitter源码解析

在Node.js中,EventEmitter类是发布订阅模式的核心。它提供了一系列用于发布和订阅事件的API,让您能够轻松构建出功能强大的异步应用。我们不妨深入EventEmitter的源码,探寻它的奥秘。

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

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

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

  removeListener(eventName, listener) {
    if (this._events[eventName]) {
      this._events[eventName] = this._events[eventName].filter(
        (l) => l !== listener
      );
    }
  }
}

从上述代码可以看出,EventEmitter类维护了一个_events对象,用于存储所有已注册的事件及其对应的监听器。当您调用on()方法时,它会将新的监听器添加到指定事件的监听器数组中。当调用emit()方法时,它会遍历该数组并调用每个监听器,将参数args传递给它们。最后,removeListener()方法则用于从指定的事件中移除监听器。

基于发布订阅模式构建异步应用

现在,让我们基于发布订阅模式来构建一个简单的异步应用。首先,创建一个EventEmitter类的实例:

const eventEmitter = new EventEmitter();

然后,创建一个订阅者函数,用于监听特定事件并执行相应的操作:

const subscriber = (data) => {
  console.log(`Received data: ${data}`);
};

最后,通过调用on()方法将订阅者函数注册到EventEmitter实例中:

eventEmitter.on('data', subscriber);

现在,我们就可以通过调用emit()方法来触发该事件,并将数据传递给订阅者函数:

eventEmitter.emit('data', 'Hello, world!');

当您运行此代码时,控制台将输出"Received data: Hello, world!",表明订阅者函数成功地接收到了发布者发送的数据。

结语

通过本文的介绍,您已经对发布订阅模式以及Node.js的EventEmitter源码有了初步的了解。掌握这些知识,将助力您在构建异步应用时游刃有余,并编写出更具可维护性和可扩展性的代码。