完全理解 Node.js 中的 "EventEmitter"

阅读时长 6 分钟读完

在 Node.js 中,EventEmitter 是一个非常重要的模块,它提供了一种异步事件驱动的编程方式,可以让代码具有更好的可扩展性和可维护性。本文将详细介绍 EventEmitter 的使用和实现原理,并给出示例代码以便读者更好地理解。

EventEmitter 的基本用法

EventEmitter 可以看作是一个观察者模式的实现,其基本机制是通过订阅和发布事件的方式实现异步通信。一个 EventEmitter 对象一般会有多个监听事件,当一个事件被触发时,所有绑定了该事件名的监听器都会被自动调用。下面是 EventEmitter 的基本用法示例:

-- -------------------- ---- -------
-- -- ------------ --
----- ------------ - ------------------

-- -- ------------ --
----- ------- - --- ---------------

-- --------
------------------- ------ ----- -- -
  ------------------------ ----- ------
---

------------------- ------ ----- -- -
  ------------------------ ----- ------
---

-- ----
--------------------- -------- ---------

在上面的示例中,我们首先引入了 EventEmitter 模块,然后创建了一个 EventEmitter 实例。接着通过 on 方法给事件 event 分别绑定了两个监听器函数,每个函数都会打印出两个参数 arg1arg2。最后通过 emit 方法触发了事件 event。运行代码后可以看到控制台输出了两行信息,即分别由上面两个监听器函数打印的信息。

EventEmiter 的特殊事件

EventEmitter 有两个比较特殊的事件:newListenerremoveListener。在添加或删除事件监听器时,如果添加或删除的操作成功了,则会触发 newListenerremoveListener 事件。

newListener 事件的监听函数会接受两个参数,第一个参数是添加监听器的事件名,第二个参数是添加的监听器函数。

removeListener 事件的监听函数会接受两个参数,第一个参数是被移除监听器的事件名,第二个参数是被移除的监听器函数。

下面是一个使用 newListenerremoveListener 事件的示例:

-- -------------------- ---- -------
------------------------- -------------- --------- -
  ------------------ -------- ------ - - ------
---

---------------------------- -------------- --------- -
  ------------------ -------- -------- - - ------
---

----- --------- - -- -- -
  -------------------------
-

------------------- -----------

------------------------------- -----------

在上面的示例中,我们先用 on 方法添加了 newListenerremoveListener 两个事件的监听器,然后通过 on 方法给事件 event 绑定了一个新的监听函数。最后通过 removeLisenter 方法将该监听器从事件 event 上移除。运行代码后会输出 'Event listener added: event''Event listener removed: event',说明监听器的添加和移除是成功的。

EventEmitter 的实现原理

EventEmitter 的实现原理可以分为两部分:一是 EventEmitter 对象本身,二是绑定和触发事件的机制。

在 EventEmitter 对象本身的实现中,我们可以通过源代码来了解其实现方式。在 Node.js 源代码中,EventEmitter 对象是使用 JavaScript 中的类和原型继承来实现的。下面是一个简单的 EventEmitter 源码示例:

-- -------------------- ---- -------
----- ------------ -
  ------------- -
    ------------ - ---
  -

  --------- --------- -
    -- ------- ------------------- --- --------- -
      ------------------- - ---
    -

    -----------------------------------
  -

  ----------- -------- -
    -- ------- ------------------- --- --------- -
      ----- --------- - --------------------
      --- ---- - - -- - - ----------------- ---- -
        ------------------------ ------
      -
    -
  -
-

在上面的源码中,我们定义了一个 EventEmitter 类,并在其构造函数中初始化了一个 _events 属性,该属性用于保存事件监听器列表。

on 方法中,我们首先通过 typeof 检查 _events 对象上是否已存在该事件的监听器列表,如果不存在就将其初始化为空数组。然后将传入的监听器函数添加到该数组中。

emit 方法中,我们单独判断一下 _events 对象上是否已存在该事件的监听器列表,并在遍历该事件的监听器函数列表时使用 apply 方法调用每一个监听器函数,并将调用时的 this 指向当前 EventEmitter 对象。

除了 EventEmitter 对象本身的实现外,还有一个非常重要的机制是绑定和触发事件的机制。在这个机制中,我们需要掌握三个重要的概念:事件名、监听器函数列表和事件参数。当一个事件被触发时,所有已经绑定了该事件名的监听器函数列表都将被自动调用,并且可以向这些监听器函数传递参数。

EventEmitter 的应用场景

使用 EventEmitter 可以实现很多针对异步编程的场景,比如:

  1. 多个异步操作串行执行,可以用 EventEmitter 将这些操作结合到一起形成一个流程,在每一个异步操作完成后才触发下一个异步操作。
  2. 多个异步操作并行执行,可以用 EventEmitter 给每一个异步操作添加一个监听器函数,在所有异步操作完成后再触发最终的回调函数。
  3. 多个模块之间的通信,可以用 EventEmitter 实现模块间的发布/订阅机制,避免模块之间直接的耦合关系。
  4. 实现一个简单的事件系统,可以用 EventEmitter 对象来实现浏览器端缺失的事件机制,例如实现一个简单的自定义事件、消息通知等功能。

总结

在本文中,我们深入探讨了 EventEmitter 在 Node.js 中的应用,并从基本用法、特殊事件、实现原理和应用场景等四个方面介绍了 EventEmitter。通过阅读本文,读者可以深入了解 EventEmitter,并在实际应用中使用它的优秀特性,提高自己的前端开发能力。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64b3c6ec48841e98940026f1

纠错
反馈