Node.js 事件模块

摘要:在本教程中,您将学习 Node.js events 模块及其工作原理。

Node.js 事件模块简介

Node.js 是事件驱动的。它依赖于 events 核心模块来实现事件驱动架构。

在事件驱动模型中,EventEmitter 对象会触发一个事件,该事件会导致先前附加到该事件的监听器执行。

EventEmitter 对象有两个主要功能

  • 发出一个命名事件。
  • 附加和分离一个或多个事件监听器到命名事件。

在 Node.js 中,许多核心模块继承了 EventEmitter 类,包括 http 模块。

以下示例说明了如何使用 events 模块。

首先,使用 require() 函数包含 events 模块

const EventEmitter = require('events');Code language: JavaScript (javascript)

EventEmitter 是一个类,因此按照惯例,它的名称采用骆驼式大小写。

其次,创建一个新的 EventEmitter 类实例

const emitter = new EventEmitter();Code language: JavaScript (javascript)

第三,使用 on() 方法将一个或多个事件处理程序附加到事件

emitter.on('saved', ) => {
    console.log(`A saved event occurred.`);
});Code language: JavaScript (javascript)

在此示例中,事件名称为 saved,事件处理程序是一个回调函数。当 saved 事件发生时,回调函数会自动调用。

最后,使用 EventEmitter 对象的 emit() 方法发出 saved 事件

emitter.emit('saved');Code language: JavaScript (javascript)

将它们放在一起

const EventEmitter = require('events');

const emitter = new EventEmitter();

emitter.on('saved', () => {
    console.log(`A saved event occurred.`);
});

emitter.emit('saved');Code language: JavaScript (javascript)

输出

A saved event occurred.
Code language: JavaScript (javascript)

使用参数发出事件

在触发事件时,您可能希望将一些数据传递给事件监听器,例如,当 saved 事件发生时已保存的对象。在这种情况下,您可以将数据作为第二个参数传递到 emit() 方法中。例如

const EventEmitter = require('events');

const emitter = new EventEmitter();

emitter.on('saved',  (arg) => {
    console.log(`A saved event occurred: name: ${arg.name}, id: ${arg.id}`);
});

emitter.emit('saved', {
    id: 1,
    name: 'John Doe'
});Code language: JavaScript (javascript)

输出

A saved event occurred, name: John Doe, id: 1Code language: JavaScript (javascript)

在此示例中,当我们发出 saved 事件时,我们将包含两个属性 idname 的对象传递给 emit() 方法。当事件发生时,我们会将对象属性显示到控制台中。

分离事件监听器

要从事件中分离事件监听器,可以使用 EventEmitter 对象的 off() 方法。例如

const EventEmitter = require('events');

const emitter = new EventEmitter();

// declare the event handler
function log(arg) {
    console.log(`A saved event occurred, name: ${arg.name}, id: ${arg.id}`);
}

// attach the event listener to the saved event
emitter.on('saved', log);

// emit the saved event
emitter.emit('saved', {
    id: 1,
    name: 'John Doe'
});

// remove the event listener
emitter.off('saved', log);

// no effect
emitter.emit('saved', {
    id: 2,
    name: 'Jane Doe'
});Code language: JavaScript (javascript)

输出

A saved event occurred, name: John Doe, id: 1

在此示例中,在从事件中分离事件监听器之后。当 saved 事件发出时,不会调用事件监听器。

扩展 EventEmitter 类

以下示例说明了如何扩展 EventEmitter

const EventEmitter = require('events');

class Stock extends EventEmitter {
    constructor(symbol, price) {
        super();
        this._symbol = symbol;
        this._price = price;
    }
    set price(newPrice) {
        if (newPrice !== this._price) {
            this.emit('PriceChanged', {
                symbol: this._symbol,
                oldPrice: this._price,
                newPrice: newPrice,
                adjustment: ((newPrice - this._price) * 100 / this._price).toFixed(2)
            });
        }
    }
    get price() {
        return this._price;
    }
    get symbol() {
        return this._symbol;
    }
}
Code language: JavaScript (javascript)

它的工作原理。

  • Stock 类扩展了 EventEmitter 类。它有两个属性:symbolprice
  • price 发生变化时,price 设置器会发出 PriceChanged 事件,并包含一个对象。

以下说明了如何使用 Stock

const stock = new Stock('AAPL', 700);

stock.on('PriceChanged', (arg) => {
    console.log(`The price of the stock ${arg.symbol} has changed ${arg.adjustment}%`);
})

stock.price = 720;
Code language: JavaScript (javascript)

输出

The price of the stock AAPL has changed 2.86%Code language: JavaScript (javascript)

摘要

  • Node.js events 模块为您提供了 EventEmitter 类,允许您在节点应用程序中管理事件。
  • 使用 EventEmitter 对象的 on() 方法为事件注册事件处理程序。
  • 使用 EventEmitter 对象的 emit() 方法发出事件。
本教程是否有帮助?