📜  Node.js 事件

📅  最后修改于: 2022-05-13 01:56:22.442000             🧑  作者: Mango

Node.js 事件

根据 Node.js 的官方文档,它是一个异步事件驱动的 JavaScript 运行时。 Node.js 有一个事件驱动的架构,可以执行异步任务。 Node.js 有'events'模块,它发出命名事件,可以导致调用相应的函数或回调。 Functions(Callbacks) 侦听或订阅要发生的特定事件,当该事件触发时,订阅该事件的所有回调都会按照注册的顺序一一触发。

EventEmmitter 类:所有发出事件的对象都是 EventEmitter 类的实例。可以在 EventEmitter 的帮助下发出或监听事件。

句法:

const EventEmitter=require('events');
var eventEmitter=new EventEmitter();

监听事件:在发出任何事件之前,它必须注册函数(回调)来监听事件。
句法:

eventEmitter.addListener(event, listener)
eventEmitter.on(event, listener)
eventEmitter.once(event, listener)

eventEmmitter.on(event, listener)eventEmitter.addListener(event, listener)非常相似。它将侦听器添加到指定事件的侦听器数组的末尾。对同一事件和侦听器的多次调用将多次添加侦听器并相应地触发多次。这两个函数都返回发射器,因此可以链接调用。

eventEmitter.once(event, listener)最多为特定事件触发一次,并在侦听一次后从 listeners 数组中删除。返回发射器,因此可以链接调用。

发射事件:每个事件在 nodejs 中都被命名为事件。我们可以通过 emit(event, [arg1], [arg2], […])函数触发一个事件。我们可以将任意一组参数传递给侦听器函数。

句法:

eventEmitter.emit(event, [arg1], [arg2], [...])

简单事件:

// Importing events
const EventEmitter = require('events');
   
// Initializing event emitter instances 
var eventEmitter = new EventEmitter();
  
// Registering to myEvent 
eventEmitter.on('myEvent', (msg) => {
   console.log(msg);
});
  
// Triggering myEvent
eventEmitter.emit('myEvent', "First event");

输出:

First event

删除监听器: eventEmitter.removeListener()接受两个参数事件和监听器,并从订阅该事件的监听器数组中删除该监听器。而eventEmitter.removeAllListeners()从数组中删除所有订阅了上述事件的侦听器。

句法:

eventEmitter.removeListener(event, listener)
eventEmitter.removeAllListeners([event])

笔记:

  • 从数组中移除监听器会改变监听器数组的顺序,因此必须小心使用。
  • eventEmitter.removeListener()将最多删除队列前面的侦听器实例。
// Importing events
const EventEmitter = require('events');
  
// Initializing event emitter instances 
var eventEmitter = new EventEmitter();
   
var fun1 = (msg) => {
    console.log("Message from fun1: " + msg);
};
   
var fun2 = (msg) => {
    console.log("Message from fun2: " + msg);
};
  
// Registering fun1 and fun2
eventEmitter.on('myEvent', fun1);
eventEmitter.on('myEvent', fun1);
eventEmitter.on('myEvent', fun2);
   
// Removing listener fun1 that was
// registered on the line 13
eventEmitter.removeListener('myEvent', fun1);
   
// Triggering myEvent
eventEmitter.emit('myEvent', "Event occurred");
  
// Removing all the listeners to myEvent
eventEmitter.removeAllListeners('myEvent');
  
// Triggering myEvent
eventEmitter.emit('myEvent', "Event occurred");

输出:

Message from fun1: Event occurred
Message from fun2: Event occurred

我们注册了两次 fun1 和一次 fun2 来调用 eventEmitter.removeListener('myEvent', fun1) 一个 fun1 的实例将被删除。最后,通过 removeAllListeners() 删除所有侦听器将删除 myEvent 的所有侦听器。

其他方法:默认情况下,一个事件最多可以注册10个监听器。要更改所有 EventEmitter 实例的默认值,可以使用EventEmitter.defaultMaxListeners属性。 eventEmitter.getMaxListeners()将返回由 setMaxListeners() 设置的最大侦听器值或默认值 10。

注意:这不是硬性限制。 EventEmitter 将允许添加新实例,但会打印一条警告消息,指示可能的 EventEmitter 内存泄漏。

句法:

eventEmitter.setMaxListeners(n)
eventEmitter.getMaxListeners()
// Importing events
const EventEmitter = require('events');
  
// Initializing event emitter instances 
var eventEmitter1 = new EventEmitter();
var eventEmitter2 = new EventEmitter();
  
// Getting max listener
console.log("Default max listener for eventEmitter1 is: ",
               eventEmitter1.getMaxListeners());
console.log("Default max listener for eventEmitter2 is: ",
              eventEmitter2.getMaxListeners());
  
// Set global deaultMaxListeners to 2
EventEmitter.defaultMaxListeners = 2;
  
// Getting max listener
console.log("Default max listener for eventEmitter1 is: ",
               eventEmitter1.getMaxListeners());
console.log("Default max listener for eventEmitter2 is: ",
               eventEmitter2.getMaxListeners());
  
// Set max listener of eventEmitter1 to 5
eventEmitter1.setMaxListeners(5);
  
// Getting max listener
console.log("Default max listener for eventEmitter1 is: ",
               eventEmitter1.getMaxListeners());
console.log("Default max listener for eventEmitter2 is: ",
               eventEmitter2.getMaxListeners());
  
// Declaring listener fun1 to myEvent1
var fun1 = (msg) => {
    console.log("Message from fun1: " + msg);
};
  
// Declaring listener fun2 to myEvent2
var fun2 = (msg) => {
    console.log("Message from fun2: " + msg);
};
  
// Listening to myEvent1 with 3 instance of fun1
for(var i = 0; i < 3; i++) {
    eventEmitter1.addListener('myEvent1', fun1)
}
  
// Listening to myEvent2 with 3 instance of fun2
for(var i = 0; i < 3; i++){
    eventEmitter2.addListener('myEvent2', fun2)
}
  
// Emitting myEvent1 and myEvent2
eventEmitter1.emit('myEvent1', 'Event1 occurred');
eventEmitter2.emit('myEvent2', 'Event2 occurred');

输出:

Default max listener for eventEmitter1 is:  10
Default max listener for eventEmitter2 is:  10
Default max listener for eventEmitter1 is:  2
Default max listener for eventEmitter2 is:  2
Default max listener for eventEmitter1 is:  5
Default max listener for eventEmitter2 is:  2
Message from fun1: Event1 occurred
Message from fun1: Event1 occurred
Message from fun1: Event1 occurred
Message from fun2: Event2 occurred
Message from fun2: Event2 occurred
Message from fun2: Event2 occurred
(node:16240) MaxListenersExceededWarning: Possible EventEmitter memory leak detected.
3 myEvent2 listeners added. Use emitter.setMaxListeners() to increase limit

eventEmitter.listeners():它返回指定事件的侦听器数组。
句法:

eventEmitter.listeners(event)

eventEmitter.listenerCount():返回监听指定事件的监听器数量。
句法:

eventEmitter.listenerCount(event)

eventEmitter.prependOnceListener():它将一次性监听器添加到数组的开头。
句法:

eventEmitter.prependOnceListener(event, listener)

eventEmitter.prependListener():它将监听器添加到数组的开头。
句法:

eventEmitter.prependListener(event, listener)
// Importing events
const EventEmitter = require('events');
  
// Initializing event emitter instances 
var eventEmitter = new EventEmitter();
  
// Declaring listener fun1 to myEvent1
var fun1 = (msg) => {
    console.log("Message from fun1: " + msg);
};
  
// Declaring listener fun2 to myEvent2
var fun2 = (msg) => {
    console.log("Message from fun2: " + msg);
};
  
// Listening to myEvent with fun1 and fun2
eventEmitter.addListener('myEvent', fun1);
  
// fun2 will be inserted in front of listeners array
eventEmitter.prependListener('myEvent', fun2);
  
// Listing listeners
console.log(eventEmitter.listeners('myEvent'));
  
// Count the listeners registered to myEvent
console.log(eventEmitter.listenerCount('myEvent'));
  
// Triggering myEvent
eventEmitter.emit('myEvent', 'Event occurred');

输出:

[ [Function: fun2], [Function: fun1] ]
2
Message from fun2: Event occurred
Message from fun1: Event occurred

特殊事件:所有 EventEmitter 实例都会在添加新侦听器并删除现有侦听器“removeListener”时发出事件“newListener”

  • 事件:'newListener' EventEmitter 实例将在将侦听器添加到其内部侦听器数组之前发出自己的“newListener”事件。为“newListener”事件注册的侦听器将被传递给事件名称和对正在添加的侦听器的引用。在将侦听器添加到数组之前触发事件“newListener”。
    eventEmitter.once( 'newListener', listener)
    eventEmitter.on( 'newListener', listener)
  • 事件:'removeListener' 'removeListener'事件在监听器被移除后触发。
    eventEmitter.once( ‘removeListener’, listener)
    eventEmitter.on( 'removeListener’, listener)
  • Event: 'error'当 EventEmitter 实例中发生错误时,典型的操作是发出一个'error'事件。如果 EventEmitter 没有为 'error' 事件注册至少一个侦听器,并且发出了 'error' 事件,则抛出错误,打印堆栈跟踪,并退出 Node.js 进程。
    eventEmitter.on('error', listener)
    
// Importing events
const EventEmitter = require('events');
  
// Initializing event emitter instances 
var eventEmitter = new EventEmitter();
  
// Register to error
eventEmitter.on('error', (err) => {
    console.error('whoops! there was an error');
});
  
// Register to newListener
eventEmitter.on( 'newListener', (event, listener) => {
    console.log(`The listener is added to ${event}`);
});
  
// Register to removeListener
eventEmitter.on( 'removeListener', (event, listener) => {
    console.log(`The listener is removed from ${event}`);
});
  
// Declaring listener fun1 to myEvent1
var fun1 = (msg) => {
    console.log("Message from fun1: " + msg);
};
  
// Declaring listener fun2 to myEvent2
var fun2 = (msg) => {
    console.log("Message from fun2: " + msg);
};
  
// Listening to myEvent with fun1 and fun2
eventEmitter.on('myEvent', fun1);
eventEmitter.on('myEvent', fun2);
  
// Removing listener
eventEmitter.off('myEvent', fun1);
  
// Triggering myEvent
eventEmitter.emit('myEvent', 'Event occurred');
  
// Triggering error
eventEmitter.emit('error', new Error('whoops!'));

输出:

The listener is added to removeListener
The listener is added to myEvent
The listener is added to myEvent
The listener is removed from myEvent
Message from fun2: Event occurred
whoops! there was an error

异步事件: EventEmitter 同步调用所有侦听器,按照它们注册的顺序。但是,我们可以使用setImmediate() 或 process.nextTick()来执行异步调用。

// Importing events
const EventEmitter = require('events');
  
// Initializing event emitter instances 
var eventEmitter = new EventEmitter();
  
// Async function listening to myEvent
eventEmitter.on('myEvent', (msg) => {
    setImmediate( () => {
        console.log("Message from async: " + msg);
    });
});
  
// Declaring listener fun to myEvent
var fun = (msg) => {
    console.log("Message from fun: " + msg);
};
  
// Listening to myEvent with fun
eventEmitter.on('myEvent', fun);
  
// Triggering myEvent
eventEmitter.emit('myEvent', "Event occurred");

输出:

Message from fun: Event occurred
Message from async: Event occurred

参考: https://nodejs.org/api/events.html