Eventi
[Stabile: 2 - Stabile]
Stabile: 2 Stabilità: 2 - Stabile
Codice sorgente: lib/events.js
Gran parte dell'API principale di Node.js è costruita attorno a un'architettura asincrona idiomatica guidata dagli eventi in cui determinati tipi di oggetti (chiamati "emettitori") emettono eventi denominati che fanno sì che gli oggetti Function ("listener") vengano chiamati.
Ad esempio: un oggetto net.Server emette un evento ogni volta che un peer si connette ad esso; un fs.ReadStream emette un evento quando il file viene aperto; uno stream emette un evento ogni volta che i dati sono disponibili per essere letti.
Tutti gli oggetti che emettono eventi sono istanze della classe EventEmitter. Questi oggetti espongono una funzione eventEmitter.on() che consente di collegare una o più funzioni a eventi denominati emessi dall'oggetto. In genere, i nomi degli eventi sono stringhe in camel-case, ma è possibile utilizzare qualsiasi chiave di proprietà JavaScript valida.
Quando l'oggetto EventEmitter emette un evento, tutte le funzioni collegate a quello specifico evento vengono chiamate sincronamente. Tutti i valori restituiti dai listener chiamati vengono ignorati e scartati.
L'esempio seguente mostra una semplice istanza EventEmitter con un singolo listener. Il metodo eventEmitter.on() viene utilizzato per registrare i listener, mentre il metodo eventEmitter.emit() viene utilizzato per attivare l'evento.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');Passaggio di argomenti e this ai listener
Il metodo eventEmitter.emit() consente di passare un set arbitrario di argomenti alle funzioni listener. Tieni presente che quando viene chiamata una normale funzione listener, la parola chiave standard this viene intenzionalmente impostata per fare riferimento all'istanza EventEmitter a cui è collegato il listener.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this, this === myEmitter);
// Prints:
// a b MyEmitter {
// _events: [Object: null prototype] { event: [Function (anonymous)] },
// _eventsCount: 1,
// _maxListeners: undefined,
// [Symbol(shapeMode)]: false,
// [Symbol(kCapture)]: false
// } true
});
myEmitter.emit('event', 'a', 'b');const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this, this === myEmitter);
// Prints:
// a b MyEmitter {
// _events: [Object: null prototype] { event: [Function (anonymous)] },
// _eventsCount: 1,
// _maxListeners: undefined,
// [Symbol(shapeMode)]: false,
// [Symbol(kCapture)]: false
// } true
});
myEmitter.emit('event', 'a', 'b');È possibile utilizzare le Funzioni Arrow ES6 come listener, tuttavia, quando si fa ciò, la parola chiave this non farà più riferimento all'istanza EventEmitter:
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b undefined
});
myEmitter.emit('event', 'a', 'b');const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');Asincrono vs. sincrono
L'EventEmitter chiama tutti i listener in modo sincrono nell'ordine in cui sono stati registrati. Questo garantisce la corretta sequenza degli eventi e aiuta a evitare race condition ed errori logici. Quando appropriato, le funzioni listener possono passare a una modalità di funzionamento asincrona utilizzando i metodi setImmediate() o process.nextTick():
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
setImmediate(() => {
console.log('questo accade in modo asincrono');
});
});
myEmitter.emit('event', 'a', 'b');const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
setImmediate(() => {
console.log('questo accade in modo asincrono');
});
});
myEmitter.emit('event', 'a', 'b');Gestire gli eventi una sola volta
Quando un listener è registrato utilizzando il metodo eventEmitter.on(), quel listener viene invocato ogni volta che l'evento denominato viene emesso.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2Utilizzando il metodo eventEmitter.once(), è possibile registrare un listener che viene chiamato al massimo una volta per un particolare evento. Una volta che l'evento viene emesso, il listener viene deregistrato e poi chiamato.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Ignoredconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// IgnoredEventi di errore
Quando si verifica un errore all'interno di un'istanza di EventEmitter, l'azione tipica è l'emissione di un evento 'error'. Questi sono trattati come casi speciali all'interno di Node.js.
Se un EventEmitter non ha almeno un listener registrato per l'evento 'error', e viene emesso un evento 'error', l'errore viene lanciato, viene stampato uno stack trace e il processo Node.js si chiude.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Lancia un'eccezione e arresta Node.jsconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Lancia un'eccezione e arresta Node.jsPer proteggersi dall'arresto anomalo del processo Node.js, è possibile utilizzare il modulo domain. (Si noti, tuttavia, che il modulo node:domain è deprecato.)
Come buona pratica, i listener devono sempre essere aggiunti per gli eventi 'error'.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Stampa: whoops! there was an errorconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Stampa: whoops! there was an errorÈ possibile monitorare gli eventi 'error' senza consumare l'errore emesso installando un listener usando il simbolo events.errorMonitor.
import { EventEmitter, errorMonitor } from 'node:events';
const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Lancia ancora un'eccezione e arresta Node.jsconst { EventEmitter, errorMonitor } = require('node:events');
const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Lancia ancora un'eccezione e arresta Node.jsCatturare i rifiuti delle promesse
L'uso di funzioni async con gestori di eventi è problematico, perché può portare a un rifiuto non gestito in caso di eccezione lanciata:
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
ee.on('something', async (value) => {
throw new Error('kaboom');
});const EventEmitter = require('node:events');
const ee = new EventEmitter();
ee.on('something', async (value) => {
throw new Error('kaboom');
});L'opzione captureRejections nel costruttore EventEmitter o l'impostazione globale modificano questo comportamento, installando un gestore .then(undefined, handler) sulla Promise. Questo gestore indirizza l'eccezione in modo asincrono al metodo Symbol.for('nodejs.rejection') se presente, o al gestore di eventi 'error' se non presente.
import { EventEmitter } from 'node:events';
const ee1 = new EventEmitter({ captureRejections: true });
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);
const ee2 = new EventEmitter({ captureRejections: true });
ee2.on('something', async (value) => {
throw new Error('kaboom');
});
ee2[Symbol.for('nodejs.rejection')] = console.log;const EventEmitter = require('node:events');
const ee1 = new EventEmitter({ captureRejections: true });
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);
const ee2 = new EventEmitter({ captureRejections: true });
ee2.on('something', async (value) => {
throw new Error('kaboom');
});
ee2[Symbol.for('nodejs.rejection')] = console.log;Impostare events.captureRejections = true cambierà il valore predefinito per tutte le nuove istanze di EventEmitter.
import { EventEmitter } from 'node:events';
EventEmitter.captureRejections = true;
const ee1 = new EventEmitter();
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);const events = require('node:events');
events.captureRejections = true;
const ee1 = new events.EventEmitter();
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);Gli eventi 'error' che vengono generati dal comportamento captureRejections non hanno un gestore catch per evitare loop di errore infiniti: la raccomandazione è di non usare funzioni async come gestori di eventi 'error'.
Classe: EventEmitter
[Cronologia]
| Versione | Modifiche |
|---|---|
| v13.4.0, v12.16.0 | Aggiunta l'opzione captureRejections. |
| v0.1.26 | Aggiunta in: v0.1.26 |
La classe EventEmitter è definita ed esposta dal modulo node:events:
import { EventEmitter } from 'node:events';const EventEmitter = require('node:events');Tutti gli EventEmitter emettono l'evento 'newListener' quando vengono aggiunti nuovi listener e 'removeListener' quando i listener esistenti vengono rimossi.
Supporta la seguente opzione:
captureRejections<boolean> Abilita l'acquisizione automatica del rifiuto della promessa. Predefinito:false.
Evento: 'newListener'
Aggiunto in: v0.1.26
eventName<string> | <symbol> Il nome dell'evento in ascoltolistener<Function> La funzione handler dell'evento
L'istanza EventEmitter emetterà il proprio evento 'newListener' prima che un listener venga aggiunto al suo array interno di listener.
Ai listener registrati per l'evento 'newListener' vengono passati il nome dell'evento e un riferimento al listener che viene aggiunto.
Il fatto che l'evento venga attivato prima di aggiungere il listener ha un effetto collaterale sottile ma importante: qualsiasi listener aggiuntivo registrato allo stesso name all'interno del callback 'newListener' viene inserito prima del listener che è in fase di aggiunta.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// Fallo solo una volta in modo da non andare in loop all'infinito
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Inserisci un nuovo listener davanti
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Stampa:
// B
// Aconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// Fallo solo una volta in modo da non andare in loop all'infinito
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Inserisci un nuovo listener davanti
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Stampa:
// B
// AEvento: 'removeListener'
[Cronologia]
| Versione | Modifiche |
|---|---|
| v6.1.0, v4.7.0 | Per i listener collegati tramite .once(), l'argomento listener ora restituisce la funzione listener originale. |
| v0.9.3 | Aggiunto in: v0.9.3 |
eventName<string> | <symbol> Il nome dell'eventolistener<Function> La funzione di gestione dell'evento
L'evento 'removeListener' viene emesso dopo che il listener è stato rimosso.
emitter.addListener(eventName, listener)
Aggiunto in: v0.1.26
eventName<string> | <symbol>listener<Function>
Alias per emitter.on(eventName, listener).
emitter.emit(eventName[, ...args])
Aggiunto in: v0.1.26
Chiama in modo sincrono ciascuno dei listener registrati per l'evento denominato eventName, nell'ordine in cui sono stati registrati, passando a ciascuno gli argomenti forniti.
Restituisce true se l'evento aveva dei listener, false altrimenti.
import { EventEmitter } from 'node:events';
const myEmitter = new EventEmitter();
// Primo listener
myEmitter.on('event', function firstListener() {
console.log('Ciao! primo listener');
});
// Secondo listener
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`evento con parametri ${arg1}, ${arg2} nel secondo listener`);
});
// Terzo listener
myEmitter.on('event', function thirdListener(...args) {
const parameters = args.join(', ');
console.log(`evento con parametri ${parameters} nel terzo listener`);
});
console.log(myEmitter.listeners('event'));
myEmitter.emit('event', 1, 2, 3, 4, 5);
// Prints:
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Ciao! primo listener
// evento con parametri 1, 2 nel secondo listener
// evento con parametri 1, 2, 3, 4, 5 nel terzo listenerconst EventEmitter = require('node:events');
const myEmitter = new EventEmitter();
// Primo listener
myEmitter.on('event', function firstListener() {
console.log('Ciao! primo listener');
});
// Secondo listener
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`evento con parametri ${arg1}, ${arg2} nel secondo listener`);
});
// Terzo listener
myEmitter.on('event', function thirdListener(...args) {
const parameters = args.join(', ');
console.log(`evento con parametri ${parameters} nel terzo listener`);
});
console.log(myEmitter.listeners('event'));
myEmitter.emit('event', 1, 2, 3, 4, 5);
// Prints:
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Ciao! primo listener
// evento con parametri 1, 2 nel secondo listener
// evento con parametri 1, 2, 3, 4, 5 nel terzo listeneremitter.eventNames()
Aggiunto in: v6.0.0
- Restituisce: <Array>
Restituisce un array elencando gli eventi per i quali l'emettitore ha registrato dei listener. I valori nell'array sono stringhe o Symbol.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});
const sym = Symbol('symbol');
myEE.on(sym, () => {});
console.log(myEE.eventNames());
// Prints: [ 'foo', 'bar', Symbol(symbol) ]const EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});
const sym = Symbol('symbol');
myEE.on(sym, () => {});
console.log(myEE.eventNames());
// Prints: [ 'foo', 'bar', Symbol(symbol) ]emitter.getMaxListeners()
Aggiunto in: v1.0.0
- Restituisce: <integer>
Restituisce il valore massimo attuale del listener per EventEmitter che è impostato da emitter.setMaxListeners(n) o predefinito a events.defaultMaxListeners.
emitter.listenerCount(eventName[, listener])
[Cronologia]
| Versione | Modifiche |
|---|---|
| v19.8.0, v18.16.0 | Aggiunto l'argomento listener. |
| v3.2.0 | Aggiunto in: v3.2.0 |
eventName<string> | <symbol> Il nome dell'evento in ascoltolistener<Function> La funzione di gestione dell'evento- Restituisce: <integer>
Restituisce il numero di listener in ascolto dell'evento denominato eventName. Se viene fornito listener, restituirà quante volte il listener viene trovato nell'elenco dei listener dell'evento.
emitter.listeners(eventName)
[Cronologia]
| Versione | Modifiche |
|---|---|
| v7.0.0 | Per i listener collegati tramite .once() ora restituisce i listener originali invece delle funzioni wrapper. |
| v0.1.26 | Aggiunto in: v0.1.26 |
eventName<stringa> | <simbolo>- Restituisce: <Function[]>
Restituisce una copia dell'array di listener per l'evento denominato eventName.
server.on('connection', (stream) => {
console.log('qualcuno si è connesso!');
});
console.log(util.inspect(server.listeners('connection')));
// Stampa: [ [Function] ]emitter.off(eventName, listener)
Aggiunto in: v10.0.0
eventName<stringa> | <simbolo>listener<Funzione>- Restituisce: <EventEmitter>
Alias per emitter.removeListener().
emitter.on(eventName, listener)
Aggiunto in: v0.1.101
eventName<stringa> | <simbolo> Il nome dell'evento.listener<Funzione> La funzione di callback- Restituisce: <EventEmitter>
Aggiunge la funzione listener alla fine dell'array dei listener per l'evento denominato eventName. Non vengono effettuati controlli per vedere se il listener è già stato aggiunto. Più chiamate che passano la stessa combinazione di eventName e listener comporteranno l'aggiunta del listener e la sua chiamata più volte.
server.on('connection', (stream) => {
console.log('qualcuno si è connesso!');
});Restituisce un riferimento all'EventEmitter, in modo che le chiamate possano essere concatenate.
Per impostazione predefinita, i listener degli eventi vengono richiamati nell'ordine in cui vengono aggiunti. Il metodo emitter.prependListener() può essere utilizzato in alternativa per aggiungere il listener dell'evento all'inizio dell'array dei listener.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Stampa:
// b
// aconst EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Stampa:
// b
// aemitter.once(eventName, listener)
Aggiunto in: v0.3.0
eventName<stringa> | <simbolo> Il nome dell'evento.listener<Funzione> La funzione di callback- Restituisce: <EventEmitter>
Aggiunge una funzione listener una tantum per l'evento chiamato eventName. La prossima volta che eventName viene attivato, questo listener viene rimosso e quindi invocato.
server.once('connection', (stream) => {
console.log('Ah, abbiamo il nostro primo utente!');
});Restituisce un riferimento a EventEmitter, in modo che le chiamate possano essere concatenate.
Per impostazione predefinita, i listener di eventi vengono invocati nell'ordine in cui vengono aggiunti. Il metodo emitter.prependOnceListener() può essere utilizzato come alternativa per aggiungere il listener di eventi all'inizio dell'array dei listener.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Stampa:
// b
// aconst EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Stampa:
// b
// aemitter.prependListener(eventName, listener)
Aggiunto in: v6.0.0
eventName<stringa> | <simbolo> Il nome dell'evento.listener<Funzione> La funzione di callback- Restituisce: <EventEmitter>
Aggiunge la funzione listener all'inizio dell'array di listener per l'evento chiamato eventName. Non vengono eseguiti controlli per verificare se il listener è già stato aggiunto. Più chiamate che passano la stessa combinazione di eventName e listener comporteranno l'aggiunta e la chiamata del listener più volte.
server.prependListener('connection', (stream) => {
console.log('qualcuno si è connesso!');
});Restituisce un riferimento a EventEmitter, in modo che le chiamate possano essere concatenate.
emitter.prependOnceListener(eventName, listener)
Aggiunto in: v6.0.0
eventName<stringa> | <simbolo> Il nome dell'evento.listener<Funzione> La funzione di callback- Restituisce: <EventEmitter>
Aggiunge una funzione listener una-tantum per l'evento denominato eventName all'inizio dell'array dei listener. La prossima volta che eventName viene attivato, questo listener viene rimosso, e quindi invocato.
server.prependOnceListener('connection', (stream) => {
console.log('Ah, abbiamo il nostro primo utente!');
});Restituisce un riferimento all'EventEmitter, in modo che le chiamate possano essere concatenate.
emitter.removeAllListeners([eventName])
Aggiunto in: v0.1.26
eventName<stringa> | <simbolo>- Restituisce: <EventEmitter>
Rimuove tutti i listener, o quelli dello specifico eventName.
È una cattiva pratica rimuovere i listener aggiunti altrove nel codice, in particolare quando l'istanza di EventEmitter è stata creata da qualche altro componente o modulo (ad esempio socket o flussi di file).
Restituisce un riferimento all'EventEmitter, in modo che le chiamate possano essere concatenate.
emitter.removeListener(eventName, listener)
Aggiunto in: v0.1.26
eventName<stringa> | <simbolo>listener<Funzione>- Restituisce: <EventEmitter>
Rimuove lo specifico listener dall'array dei listener per l'evento denominato eventName.
const callback = (stream) => {
console.log('qualcuno si è connesso!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);removeListener() rimuoverà, al massimo, un'istanza di un listener dall'array dei listener. Se un qualsiasi singolo listener è stato aggiunto più volte all'array dei listener per lo specifico eventName, allora removeListener() deve essere chiamato più volte per rimuovere ciascuna istanza.
Una volta che un evento viene emesso, tutti i listener ad esso collegati al momento dell'emissione vengono chiamati in ordine. Ciò implica che qualsiasi chiamata a removeListener() o removeAllListeners() dopo l'emissione e prima che l'ultimo listener termini l'esecuzione non li rimuoverà da emit() in corso. Gli eventi successivi si comportano come previsto.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
const callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};
const callbackB = () => {
console.log('B');
};
myEmitter.on('event', callbackA);
myEmitter.on('event', callbackB);
// callbackA rimuove il listener callbackB ma verrà comunque chiamato.
// Array di listener interno al momento dell'emissione [callbackA, callbackB]
myEmitter.emit('event');
// Stampa:
// A
// B
// callbackB è ora rimosso.
// Array di listener interno [callbackA]
myEmitter.emit('event');
// Stampa:
// Aconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
const callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};
const callbackB = () => {
console.log('B');
};
myEmitter.on('event', callbackA);
myEmitter.on('event', callbackB);
// callbackA rimuove il listener callbackB ma verrà comunque chiamato.
// Array di listener interno al momento dell'emissione [callbackA, callbackB]
myEmitter.emit('event');
// Stampa:
// A
// B
// callbackB è ora rimosso.
// Array di listener interno [callbackA]
myEmitter.emit('event');
// Stampa:
// APoiché i listener vengono gestiti utilizzando un array interno, chiamare questo cambierà gli indici di posizione di qualsiasi listener registrato dopo il listener che viene rimosso. Ciò non influirà sull'ordine in cui vengono chiamati i listener, ma significa che qualsiasi copia dell'array dei listener come restituito dal metodo emitter.listeners() dovrà essere ricreata.
Quando una singola funzione è stata aggiunta come gestore più volte per un singolo evento (come nell'esempio seguente), removeListener() rimuoverà l'istanza aggiunta più di recente. Nell'esempio viene rimosso il listener once('ping'):
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
function pong() {
console.log('pong');
}
ee.on('ping', pong);
ee.once('ping', pong);
ee.removeListener('ping', pong);
ee.emit('ping');
ee.emit('ping');const EventEmitter = require('node:events');
const ee = new EventEmitter();
function pong() {
console.log('pong');
}
ee.on('ping', pong);
ee.once('ping', pong);
ee.removeListener('ping', pong);
ee.emit('ping');
ee.emit('ping');Restituisce un riferimento all'EventEmitter, in modo che le chiamate possano essere concatenate.
emitter.setMaxListeners(n)
Aggiunto in: v0.3.5
n<integer>- Restituisce: <EventEmitter>
Per impostazione predefinita, gli EventEmitter stamperanno un avviso se vengono aggiunti più di 10 listener per un evento specifico. Questo è un valore predefinito utile che aiuta a trovare perdite di memoria. Il metodo emitter.setMaxListeners() consente di modificare il limite per questa specifica istanza di EventEmitter. Il valore può essere impostato su Infinity (o 0) per indicare un numero illimitato di listener.
Restituisce un riferimento all'EventEmitter, in modo che le chiamate possano essere concatenate.
emitter.rawListeners(eventName)
Aggiunto in: v9.4.0
eventName<stringa> | <simbolo>- Restituisce: <Funzione[]>
Restituisce una copia dell'array di listener per l'evento denominato eventName, inclusi eventuali wrapper (come quelli creati da .once()).
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Restituisce un nuovo Array con una funzione `onceWrapper` che ha una proprietà
// `listener` che contiene il listener originale associato sopra
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Registra "log once" sulla console e non scollega l'evento `once`
logFnWrapper.listener();
// Registra "log once" sulla console e rimuove il listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Restituirà un nuovo Array con una singola funzione associata da `.on()` sopra
const newListeners = emitter.rawListeners('log');
// Registra "log persistently" due volte
newListeners[0]();
emitter.emit('log');const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Restituisce un nuovo Array con una funzione `onceWrapper` che ha una proprietà
// `listener` che contiene il listener originale associato sopra
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Registra "log once" sulla console e non scollega l'evento `once`
logFnWrapper.listener();
// Registra "log once" sulla console e rimuove il listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Restituirà un nuovo Array con una singola funzione associata da `.on()` sopra
const newListeners = emitter.rawListeners('log');
// Registra "log persistently" due volte
newListeners[0]();
emitter.emit('log');emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])
[Cronologia]
| Versione | Modifiche |
|---|---|
| v17.4.0, v16.14.0 | Non più sperimentale. |
| v13.4.0, v12.16.0 | Aggiunto in: v13.4.0, v12.16.0 |
errErroreeventName<stringa> | <simbolo>...args<qualsiasi>
Il metodo Symbol.for('nodejs.rejection') viene chiamato nel caso in cui si verifichi un rifiuto di una promise durante l'emissione di un evento e captureRejections sia abilitato sull'emettitore. È possibile utilizzare events.captureRejectionSymbol al posto di Symbol.for('nodejs.rejection').
import { EventEmitter, captureRejectionSymbol } from 'node:events';
class MyClass extends EventEmitter {
constructor() {
super({ captureRejections: true });
}
[captureRejectionSymbol](err, event, ...args) {
console.log('si è verificato un rifiuto per', event, 'con', err, ...args);
this.destroy(err);
}
destroy(err) {
// Abbattere la risorsa qui.
}
}const { EventEmitter, captureRejectionSymbol } = require('node:events');
class MyClass extends EventEmitter {
constructor() {
super({ captureRejections: true });
}
[captureRejectionSymbol](err, event, ...args) {
console.log('si è verificato un rifiuto per', event, 'con', err, ...args);
this.destroy(err);
}
destroy(err) {
// Abbattere la risorsa qui.
}
}events.defaultMaxListeners
Aggiunto in: v0.11.2
Per impostazione predefinita, è possibile registrare un massimo di 10 listener per un singolo evento. Questo limite può essere modificato per le singole istanze di EventEmitter utilizzando il metodo emitter.setMaxListeners(n). Per modificare il valore predefinito per tutte le istanze di EventEmitter, è possibile utilizzare la proprietà events.defaultMaxListeners. Se questo valore non è un numero positivo, viene generato un RangeError.
Prestare attenzione quando si imposta events.defaultMaxListeners perché la modifica influisce su tutte le istanze di EventEmitter, comprese quelle create prima che la modifica venga apportata. Tuttavia, la chiamata a emitter.setMaxListeners(n) ha comunque la precedenza su events.defaultMaxListeners.
Questo non è un limite rigido. L'istanza di EventEmitter consentirà l'aggiunta di più listener, ma emetterà un avviso di traccia su stderr indicando che è stata rilevata una "possibile perdita di memoria di EventEmitter". Per qualsiasi singolo EventEmitter, i metodi emitter.getMaxListeners() e emitter.setMaxListeners() possono essere utilizzati per evitare temporaneamente questo avviso:
defaultMaxListeners non ha effetto sulle istanze di AbortSignal. Sebbene sia ancora possibile utilizzare emitter.setMaxListeners(n) per impostare un limite di avviso per le singole istanze di AbortSignal, per impostazione predefinita le istanze di AbortSignal non avviseranno.
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
// fare qualcosa
emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
// fare qualcosa
emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});Il flag della riga di comando --trace-warnings può essere utilizzato per visualizzare la traccia dello stack per tali avvisi.
L'avviso emesso può essere ispezionato con process.on('warning') e avrà le proprietà aggiuntive emitter, type e count, che si riferiscono rispettivamente all'istanza dell'emettitore di eventi, al nome dell'evento e al numero di listener collegati. La sua proprietà name è impostata su 'MaxListenersExceededWarning'.
events.errorMonitor
Aggiunto in: v13.6.0, v12.17.0
Questo simbolo deve essere utilizzato per installare un listener solo per il monitoraggio degli eventi 'error'. I listener installati utilizzando questo simbolo vengono chiamati prima dei normali listener 'error'.
L'installazione di un listener tramite questo simbolo non modifica il comportamento una volta emesso un evento 'error'. Pertanto, il processo si arresterà comunque in modo anomalo se non è installato alcun listener 'error' regolare.
events.getEventListeners(emitterOrTarget, eventName)
Aggiunto in: v15.2.0, v14.17.0
emitterOrTarget<EventEmitter> | <EventTarget>eventName<string> | <symbol>- Restituisce: <Function[]>
Restituisce una copia dell'array di listener per l'evento denominato eventName.
Per EventEmitter si comporta esattamente come chiamare .listeners sull'emitter.
Per EventTarget questo è l'unico modo per ottenere i listener dell'evento per il target dell'evento. Questo è utile per il debug e la diagnostica.
import { getEventListeners, EventEmitter } from 'node:events';
{
const ee = new EventEmitter();
const listener = () => console.log('Events are fun');
ee.on('foo', listener);
console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ]
}
{
const et = new EventTarget();
const listener = () => console.log('Events are fun');
et.addEventListener('foo', listener);
console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ]
}const { getEventListeners, EventEmitter } = require('node:events');
{
const ee = new EventEmitter();
const listener = () => console.log('Events are fun');
ee.on('foo', listener);
console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ]
}
{
const et = new EventTarget();
const listener = () => console.log('Events are fun');
et.addEventListener('foo', listener);
console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ]
}events.getMaxListeners(emitterOrTarget)
Aggiunto in: v19.9.0, v18.17.0
emitterOrTarget<EventEmitter> | <EventTarget>- Restituisce: <number>
Restituisce la quantità massima di listener attualmente impostata.
Per gli EventEmitter, questo si comporta esattamente come chiamare .getMaxListeners sull'emitter.
Per gli EventTarget, questo è l'unico modo per ottenere il numero massimo di listener di eventi per l'event target. Se il numero di gestori di eventi su un singolo EventTarget supera il massimo impostato, l'EventTarget stamperà un avviso.
import { getMaxListeners, setMaxListeners, EventEmitter } from 'node:events';
{
const ee = new EventEmitter();
console.log(getMaxListeners(ee)); // 10
setMaxListeners(11, ee);
console.log(getMaxListeners(ee)); // 11
}
{
const et = new EventTarget();
console.log(getMaxListeners(et)); // 10
setMaxListeners(11, et);
console.log(getMaxListeners(et)); // 11
}const { getMaxListeners, setMaxListeners, EventEmitter } = require('node:events');
{
const ee = new EventEmitter();
console.log(getMaxListeners(ee)); // 10
setMaxListeners(11, ee);
console.log(getMaxListeners(ee)); // 11
}
{
const et = new EventTarget();
console.log(getMaxListeners(et)); // 10
setMaxListeners(11, et);
console.log(getMaxListeners(et)); // 11
}events.once(emitter, name[, options])
[Cronologia]
| Versione | Modifiche |
|---|---|
| v15.0.0 | L'opzione signal è ora supportata. |
| v11.13.0, v10.16.0 | Aggiunto in: v11.13.0, v10.16.0 |
emitter<EventEmitter>options<Object>signal<AbortSignal> Può essere utilizzato per annullare l'attesa per l'evento.
Restituisce: <Promise>
Crea una Promise che viene soddisfatta quando l'EventEmitter emette l'evento specificato o che viene rifiutata se l'EventEmitter emette 'error' durante l'attesa. La Promise si risolverà con un array di tutti gli argomenti emessi all'evento specificato.
Questo metodo è intenzionalmente generico e funziona con l'interfaccia EventTarget della piattaforma web, che non ha una semantica speciale per l'evento 'error' e non ascolta l'evento 'error'.
import { once, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
process.nextTick(() => {
ee.emit('myevent', 42);
});
const [value] = await once(ee, 'myevent');
console.log(value);
const err = new Error('kaboom');
process.nextTick(() => {
ee.emit('error', err);
});
try {
await once(ee, 'myevent');
} catch (err) {
console.error('error happened', err);
}const { once, EventEmitter } = require('node:events');
async function run() {
const ee = new EventEmitter();
process.nextTick(() => {
ee.emit('myevent', 42);
});
const [value] = await once(ee, 'myevent');
console.log(value);
const err = new Error('kaboom');
process.nextTick(() => {
ee.emit('error', err);
});
try {
await once(ee, 'myevent');
} catch (err) {
console.error('error happened', err);
}
}
run();La gestione speciale dell'evento 'error' viene utilizzata solo quando events.once() viene utilizzato per attendere un altro evento. Se events.once() viene utilizzato per attendere l'evento 'error' stesso, allora viene trattato come qualsiasi altro tipo di evento senza una gestione speciale:
import { EventEmitter, once } from 'node:events';
const ee = new EventEmitter();
once(ee, 'error')
.then(([err]) => console.log('ok', err.message))
.catch((err) => console.error('error', err.message));
ee.emit('error', new Error('boom'));
// Prints: ok boomconst { EventEmitter, once } = require('node:events');
const ee = new EventEmitter();
once(ee, 'error')
.then(([err]) => console.log('ok', err.message))
.catch((err) => console.error('error', err.message));
ee.emit('error', new Error('boom'));
// Prints: ok boomUn <AbortSignal> può essere utilizzato per annullare l'attesa per l'evento:
import { EventEmitter, once } from 'node:events';
const ee = new EventEmitter();
const ac = new AbortController();
async function foo(emitter, event, signal) {
try {
await once(emitter, event, { signal });
console.log('event emitted!');
} catch (error) {
if (error.name === 'AbortError') {
console.error('Waiting for the event was canceled!');
} else {
console.error('There was an error', error.message);
}
}
}
foo(ee, 'foo', ac.signal);
ac.abort(); // Prints: Waiting for the event was canceled!const { EventEmitter, once } = require('node:events');
const ee = new EventEmitter();
const ac = new AbortController();
async function foo(emitter, event, signal) {
try {
await once(emitter, event, { signal });
console.log('event emitted!');
} catch (error) {
if (error.name === 'AbortError') {
console.error('Waiting for the event was canceled!');
} else {
console.error('There was an error', error.message);
}
}
}
foo(ee, 'foo', ac.signal);
ac.abort(); // Prints: Waiting for the event was canceled!Attesa di molteplici eventi emessi su process.nextTick()
Esiste un caso limite degno di nota quando si utilizza la funzione events.once() per attendere più eventi emessi nello stesso batch di operazioni process.nextTick(), o ogni volta che più eventi vengono emessi in modo sincrono. In particolare, poiché la coda process.nextTick() viene svuotata prima della coda dei microtask Promise, e poiché EventEmitter emette tutti gli eventi in modo sincrono, è possibile che events.once() perda un evento.
import { EventEmitter, once } from 'node:events';
import process from 'node:process';
const myEE = new EventEmitter();
async function foo() {
await once(myEE, 'bar');
console.log('bar');
// Questa Promise non si risolverà mai perché l'evento 'foo' sarà
// già stato emesso prima che la Promise venga creata.
await once(myEE, 'foo');
console.log('foo');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));const { EventEmitter, once } = require('node:events');
const myEE = new EventEmitter();
async function foo() {
await once(myEE, 'bar');
console.log('bar');
// Questa Promise non si risolverà mai perché l'evento 'foo' sarà
// già stato emesso prima che la Promise venga creata.
await once(myEE, 'foo');
console.log('foo');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));Per intercettare entrambi gli eventi, crea ciascuna delle Promise prima di attenderne una qualsiasi, quindi diventa possibile utilizzare Promise.all(), Promise.race() o Promise.allSettled():
import { EventEmitter, once } from 'node:events';
import process from 'node:process';
const myEE = new EventEmitter();
async function foo() {
await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
console.log('foo', 'bar');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));const { EventEmitter, once } = require('node:events');
const myEE = new EventEmitter();
async function foo() {
await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
console.log('foo', 'bar');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));events.captureRejections
[Cronologia]
| Versione | Modifiche |
|---|---|
| v17.4.0, v16.14.0 | Non più sperimentale. |
| v13.4.0, v12.16.0 | Aggiunto in: v13.4.0, v12.16.0 |
Valore: <boolean>
Cambia l'opzione predefinita captureRejections su tutti i nuovi oggetti EventEmitter.
events.captureRejectionSymbol
[Cronologia]
| Versione | Modifiche |
|---|---|
| v17.4.0, v16.14.0 | Non più sperimentale. |
| v13.4.0, v12.16.0 | Aggiunto in: v13.4.0, v12.16.0 |
Valore: Symbol.for('nodejs.rejection')
Vedi come scrivere un gestore di reiezione personalizzato.
events.listenerCount(emitter, eventName)
Aggiunto in: v0.9.12
Deprecato dal: v3.2.0
[Stabile: 0 - Deprecato]
Stabile: 0 Stabilità: 0 - Deprecato: Utilizza invece emitter.listenerCount().
emitter<EventEmitter> L'emettitore da interrogareeventName<string> | <symbol> Il nome dell'evento
Un metodo di classe che restituisce il numero di listener per l'eventName dato registrato sull'emitter dato.
import { EventEmitter, listenerCount } from 'node:events';
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(listenerCount(myEmitter, 'event'));
// Prints: 2const { EventEmitter, listenerCount } = require('node:events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(listenerCount(myEmitter, 'event'));
// Prints: 2events.on(emitter, eventName[, options])
[Cronologia]
| Versione | Modifiche |
|---|---|
| v22.0.0, v20.13.0 | Supporta le opzioni highWaterMark e lowWaterMark, per coerenza. Le vecchie opzioni sono ancora supportate. |
| v20.0.0 | Le opzioni close, highWatermark e lowWatermark sono ora supportate. |
| v13.6.0, v12.16.0 | Aggiunto in: v13.6.0, v12.16.0 |
emitter<EventEmitter>eventName<string> | <symbol> Il nome dell'evento in ascoltooptions<Object>signal<AbortSignal> Può essere usato per annullare gli eventi in attesa.close- <string[]> Nomi di eventi che termineranno l'iterazione.highWaterMark- <integer> Predefinito:Number.MAX_SAFE_INTEGERIl limite massimo. L'emettitore viene messo in pausa ogni volta che la dimensione degli eventi in buffer è superiore a questo valore. Supportato solo sugli emettitori che implementano i metodipause()eresume().lowWaterMark- <integer> Predefinito:1Il limite inferiore. L'emettitore viene ripreso ogni volta che la dimensione degli eventi in buffer è inferiore a questo valore. Supportato solo sugli emettitori che implementano i metodipause()eresume().
Restituisce: <AsyncIterator> che itera sugli eventi
eventNameemessi dall'emitter
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
// Emetti più tardi
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// L'esecuzione di questo blocco interno è sincrona ed elabora
// un evento alla volta (anche con await). Non usare
// se è richiesta l'esecuzione concorrente.
console.log(event); // stampa ['bar'] [42]
}
// Irraggiungibile quiconst { on, EventEmitter } = require('node:events');
(async () => {
const ee = new EventEmitter();
// Emetti più tardi
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// L'esecuzione di questo blocco interno è sincrona ed elabora
// un evento alla volta (anche con await). Non usare
// se è richiesta l'esecuzione concorrente.
console.log(event); // stampa ['bar'] [42]
}
// Irraggiungibile qui
})();Restituisce un AsyncIterator che itera sugli eventi eventName. Verrà generata un'eccezione se l'EventEmitter emette 'error'. Rimuove tutti i listener quando si esce dal loop. Il value restituito da ogni iterazione è un array composto dagli argomenti dell'evento emesso.
Un <AbortSignal> può essere utilizzato per annullare l'attesa degli eventi:
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// Emetti più tardi
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// L'esecuzione di questo blocco interno è sincrona ed elabora
// un evento alla volta (anche con await). Non usare
// se è richiesta l'esecuzione concorrente.
console.log(event); // stampa ['bar'] [42]
}
// Irraggiungibile qui
})();
process.nextTick(() => ac.abort());const { on, EventEmitter } = require('node:events');
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// Emetti più tardi
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// L'esecuzione di questo blocco interno è sincrona ed elabora
// un evento alla volta (anche con await). Non usare
// se è richiesta l'esecuzione concorrente.
console.log(event); // stampa ['bar'] [42]
}
// Irraggiungibile qui
})();
process.nextTick(() => ac.abort());events.setMaxListeners(n[, ...eventTargets])
Aggiunto in: v15.4.0
n<number> Un numero non negativo. Il numero massimo di listener per eventoEventTarget....eventsTargets<EventTarget[]> | <EventEmitter[]> Zero o più istanze di <EventTarget> o <EventEmitter>. Se non ne vengono specificate,nviene impostato come valore massimo predefinito per tutti gli oggetti <EventTarget> e <EventEmitter> appena creati.
import { setMaxListeners, EventEmitter } from 'node:events';
const target = new EventTarget();
const emitter = new EventEmitter();
setMaxListeners(5, target, emitter);const {
setMaxListeners,
EventEmitter,
} = require('node:events');
const target = new EventTarget();
const emitter = new EventEmitter();
setMaxListeners(5, target, emitter);events.addAbortListener(signal, listener)
Aggiunto in: v20.5.0, v18.18.0
[Stabile: 1 - Sperimentale]
Stabile: 1 Stabilità: 1 - Sperimentale
signal<AbortSignal>listener<Function> | <EventListener>- Restituisce: <Disposable> Un Disposable che rimuove il listener
abort.
Ascolta una volta l'evento abort sul signal fornito.
Ascoltare l'evento abort sui segnali di interruzione non è sicuro e può portare a perdite di risorse poiché un'altra terza parte con il segnale può chiamare e.stopImmediatePropagation(). Sfortunatamente Node.js non può cambiarlo poiché violerebbe lo standard web. Inoltre, l'API originale rende facile dimenticare di rimuovere i listener.
Questa API consente di utilizzare in modo sicuro gli AbortSignal nelle API di Node.js risolvendo questi due problemi ascoltando l'evento in modo tale che stopImmediatePropagation non impedisca l'esecuzione del listener.
Restituisce un disposable in modo che possa essere disiscritta più facilmente.
const { addAbortListener } = require('node:events');
function example(signal) {
let disposable;
try {
signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
disposable = addAbortListener(signal, (e) => {
// Do something when signal is aborted.
});
} finally {
disposable?.[Symbol.dispose]();
}
}import { addAbortListener } from 'node:events';
function example(signal) {
let disposable;
try {
signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
disposable = addAbortListener(signal, (e) => {
// Do something when signal is aborted.
});
} finally {
disposable?.[Symbol.dispose]();
}
}Classe: events.EventEmitterAsyncResource extends EventEmitter
Aggiunto in: v17.4.0, v16.14.0
Integra EventEmitter con <AsyncResource> per EventEmitter che richiedono il tracciamento asincrono manuale. Nello specifico, tutti gli eventi emessi dalle istanze di events.EventEmitterAsyncResource verranno eseguiti all'interno del suo contesto asincrono.
import { EventEmitterAsyncResource, EventEmitter } from 'node:events';
import { notStrictEqual, strictEqual } from 'node:assert';
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks';
// Gli strumenti di tracciamento asincrono lo identificheranno come 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// I listener 'foo' verranno eseguiti nel contesto asincrono degli EventEmitter.
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// I listener 'foo' su EventEmitter ordinari che non tracciano il contesto
// asincrono, tuttavia, vengono eseguiti nello stesso contesto asincrono di emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId);
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
});
Promise.resolve().then(() => {
ee1.emit('foo');
ee2.emit('foo');
});const { EventEmitterAsyncResource, EventEmitter } = require('node:events');
const { notStrictEqual, strictEqual } = require('node:assert');
const { executionAsyncId, triggerAsyncId } = require('node:async_hooks');
// Gli strumenti di tracciamento asincrono lo identificheranno come 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// I listener 'foo' verranno eseguiti nel contesto asincrono degli EventEmitter.
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// I listener 'foo' su EventEmitter ordinari che non tracciano il contesto
// asincrono, tuttavia, vengono eseguiti nello stesso contesto asincrono di emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId);
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
});
Promise.resolve().then(() => {
ee1.emit('foo');
ee2.emit('foo');
});La classe EventEmitterAsyncResource ha gli stessi metodi e accetta le stesse opzioni di EventEmitter e AsyncResource stessi.
new events.EventEmitterAsyncResource([options])
options<Object>captureRejections<boolean> Abilita l'acquisizione automatica del rifiuto delle promise. Predefinito:false.name<string> Il tipo di evento asincrono. Predefinito:new.target.name.triggerAsyncId<number> L'ID del contesto di esecuzione che ha creato questo evento asincrono. Predefinito:executionAsyncId().requireManualDestroy<boolean> Se impostato sutrue, disabilitaemitDestroyquando l'oggetto viene raccolto dal Garbage Collector. Di solito non è necessario impostarlo (anche seemitDestroyviene chiamato manualmente), a meno che l'asyncIddella risorsa non venga recuperato e venga chiamata laemitDestroydell'API sensibile con esso. Quando impostato sufalse, la chiamataemitDestroysul Garbage Collection avverrà solo se è presente almeno un hookdestroyattivo. Predefinito:false.
eventemitterasyncresource.asyncId
- Tipo: <number> L'
asyncIdunivoco assegnato alla risorsa.
eventemitterasyncresource.asyncResource
- Tipo: <AsyncResource> sottostante.
L'oggetto AsyncResource restituito ha una proprietà eventEmitter aggiuntiva che fornisce un riferimento a questo EventEmitterAsyncResource.
eventemitterasyncresource.emitDestroy()
Chiama tutti gli hook destroy. Questo dovrebbe essere chiamato solo una volta. Verrà generato un errore se viene chiamato più di una volta. Questo deve essere chiamato manualmente. Se la risorsa viene lasciata alla raccolta da parte del GC, gli hook destroy non verranno mai chiamati.
eventemitterasyncresource.triggerAsyncId
- Type: <number> Lo stesso
triggerAsyncIdpassato al costruttore diAsyncResource.
API EventTarget ed Event
[Cronologia]
| Versione | Modifiche |
|---|---|
| v16.0.0 | Gestione degli errori di EventTarget modificata. |
| v15.4.0 | Non più sperimentale. |
| v15.0.0 | Le classi EventTarget ed Event sono ora disponibili come globali. |
| v14.5.0 | Aggiunto in: v14.5.0 |
Gli oggetti EventTarget ed Event sono un'implementazione specifica di Node.js della EventTarget Web API che sono esposti da alcune API principali di Node.js.
const target = new EventTarget();
target.addEventListener('foo', (event) => {
console.log('evento foo accaduto!');
});EventTarget di Node.js contro EventTarget DOM
Ci sono due differenze fondamentali tra EventTarget di Node.js e la EventTarget Web API:
NodeEventTarget contro EventEmitter
L'oggetto NodeEventTarget implementa un sottoinsieme modificato dell'API EventEmitter che gli consente di emulare da vicino un EventEmitter in determinate situazioni. Un NodeEventTarget non è un'istanza di EventEmitter e non può essere utilizzato al posto di un EventEmitter nella maggior parte dei casi.
Listener di eventi
I listener di eventi registrati per un type di evento possono essere funzioni JavaScript o oggetti con una proprietà handleEvent il cui valore è una funzione.
In entrambi i casi, la funzione handler viene invocata con l'argomento event passato alla funzione eventTarget.dispatchEvent().
Le funzioni asincrone possono essere utilizzate come listener di eventi. Se una funzione handler asincrona viene rifiutata, il rifiuto viene acquisito e gestito come descritto in gestione degli errori di EventTarget.
Un errore generato da una funzione handler non impedisce l'invocazione degli altri handler.
Il valore restituito di una funzione handler viene ignorato.
Gli handler vengono sempre invocati nell'ordine in cui sono stati aggiunti.
Le funzioni handler possono mutare l'oggetto event.
function handler1(event) {
console.log(event.type); // Stampa 'foo'
event.a = 1;
}
async function handler2(event) {
console.log(event.type); // Stampa 'foo'
console.log(event.a); // Stampa 1
}
const handler3 = {
handleEvent(event) {
console.log(event.type); // Stampa 'foo'
},
};
const handler4 = {
async handleEvent(event) {
console.log(event.type); // Stampa 'foo'
},
};
const target = new EventTarget();
target.addEventListener('foo', handler1);
target.addEventListener('foo', handler2);
target.addEventListener('foo', handler3);
target.addEventListener('foo', handler4, { once: true });Gestione degli errori in EventTarget
Quando un listener di eventi registrato genera un'eccezione (o restituisce una Promise che viene rifiutata), per impostazione predefinita l'errore viene trattato come un'eccezione non gestita su process.nextTick(). Ciò significa che le eccezioni non gestite in EventTarget termineranno il processo di Node.js per impostazione predefinita.
Generare un'eccezione all'interno di un listener di eventi non impedirà l'invocazione degli altri handler registrati.
EventTarget non implementa alcuna gestione predefinita speciale per gli eventi di tipo 'error' come EventEmitter.
Attualmente, gli errori vengono prima inoltrati all'evento process.on('error') prima di raggiungere process.on('uncaughtException'). Questo comportamento è deprecato e cambierà in una versione futura per allineare EventTarget con altre API di Node.js. Qualsiasi codice che si basa sull'evento process.on('error') deve essere allineato al nuovo comportamento.
Classe: Event
[Cronologia]
| Versione | Modifiche |
|---|---|
| v15.0.0 | La classe Event è ora disponibile tramite l'oggetto globale. |
| v14.5.0 | Aggiunta in: v14.5.0 |
L'oggetto Event è un adattamento della Event Web API. Le istanze vengono create internamente da Node.js.
event.bubbles
Aggiunta in: v14.5.0
- Tipo: <boolean> Restituisce sempre
false.
Questo non viene utilizzato in Node.js ed è fornito puramente per completezza.
event.cancelBubble
Aggiunta in: v14.5.0
[Stabile: 3 - Legacy]
Stabile: 3 Stabilità: 3 - Legacy: utilizzare event.stopPropagation() invece.
- Tipo: <boolean>
Alias per event.stopPropagation() se impostato su true. Questo non viene utilizzato in Node.js ed è fornito puramente per completezza.
event.cancelable
Aggiunta in: v14.5.0
- Tipo: <boolean> True se l'evento è stato creato con l'opzione
cancelable.
event.composed
Aggiunto in: v14.5.0
- Tipo: <boolean> Restituisce sempre
false.
Questo non è utilizzato in Node.js ed è fornito puramente per completezza.
event.composedPath()
Aggiunto in: v14.5.0
Restituisce un array contenente l'EventTarget corrente come unica voce o vuoto se l'evento non viene distribuito. Questo non è utilizzato in Node.js ed è fornito puramente per completezza.
event.currentTarget
Aggiunto in: v14.5.0
- Tipo: <EventTarget> L'
EventTargetche distribuisce l'evento.
Alias per event.target.
event.defaultPrevented
Aggiunto in: v14.5.0
- Tipo: <boolean>
È true se cancelable è true e event.preventDefault() è stato chiamato.
event.eventPhase
Aggiunto in: v14.5.0
- Tipo: <number> Restituisce
0mentre un evento non viene distribuito,2mentre viene distribuito.
Questo non è utilizzato in Node.js ed è fornito puramente per completezza.
event.initEvent(type[, bubbles[, cancelable]])
Aggiunto in: v19.5.0
[Stabile: 3 - Legacy]
Stabile: 3 Stabilità: 3 - Legacy: La specifica WHATWG lo considera deprecato e gli utenti non dovrebbero usarlo affatto.
Ridondante con i costruttori di eventi e incapace di impostare composed. Questo non è utilizzato in Node.js ed è fornito puramente per completezza.
event.isTrusted
Aggiunto in: v14.5.0
- Tipo: <boolean>
L'evento "abort" di <AbortSignal> viene emesso con isTrusted impostato su true. Il valore è false in tutti gli altri casi.
event.preventDefault()
Aggiunto in: v14.5.0
Imposta la proprietà defaultPrevented su true se cancelable è true.
event.returnValue
Aggiunto in: v14.5.0
[Stabile: 3 - Legacy]
Stabile: 3 Stabilità: 3 - Legacy: Utilizzare invece event.defaultPrevented.
- Tipo: <boolean> True se l'evento non è stato annullato.
Il valore di event.returnValue è sempre l'opposto di event.defaultPrevented. Questo non viene utilizzato in Node.js ed è fornito puramente a scopo di completezza.
event.srcElement
Aggiunto in: v14.5.0
[Stabile: 3 - Legacy]
Stabile: 3 Stabilità: 3 - Legacy: Utilizzare invece event.target.
- Tipo: <EventTarget> L'
EventTargetche distribuisce l'evento.
Alias per event.target.
event.stopImmediatePropagation()
Aggiunto in: v14.5.0
Interrompe l'invocazione dei listener di eventi dopo che quello corrente è stato completato.
event.stopPropagation()
Aggiunto in: v14.5.0
Questo non viene utilizzato in Node.js ed è fornito puramente a scopo di completezza.
event.target
Aggiunto in: v14.5.0
- Tipo: <EventTarget> L'
EventTargetche distribuisce l'evento.
event.timeStamp
Aggiunto in: v14.5.0
- Tipo: <number>
Il timestamp in millisecondi quando è stato creato l'oggetto Event.
event.type
Aggiunto in: v14.5.0
- Tipo: <string>
L'identificatore del tipo di evento.
Classe: EventTarget
[Cronologia]
| Versione | Modifiche |
|---|---|
| v15.0.0 | La classe EventTarget è ora disponibile tramite l'oggetto globale. |
| v14.5.0 | Aggiunto in: v14.5.0 |
eventTarget.addEventListener(type, listener[, options])
[Cronologia]
| Versione | Modifiche |
|---|---|
| v15.4.0 | Aggiunto il supporto per l'opzione signal. |
| v14.5.0 | Aggiunto in: v14.5.0 |
type<string>listener<Function> | <EventListener>options<Object>once<boolean> Quandotrue, il listener viene rimosso automaticamente quando viene invocato per la prima volta. Predefinito:false.passive<boolean> Quandotrue, serve come suggerimento che il listener non chiamerà il metodopreventDefault()dell'oggettoEvent. Predefinito:false.capture<boolean> Non utilizzato direttamente da Node.js. Aggiunto per completezza dell'API. Predefinito:false.signal<AbortSignal> Il listener verrà rimosso quando viene chiamato il metodoabort()dell'oggetto AbortSignal specificato.
Aggiunge un nuovo gestore per l'evento type. Qualsiasi listener specificato viene aggiunto solo una volta per type e per valore dell'opzione capture.
Se l'opzione once è true, il listener viene rimosso dopo la prossima volta che viene inviato un evento type.
L'opzione capture non viene utilizzata da Node.js in alcun modo funzionale se non per tracciare i listener di eventi registrati secondo le specifiche EventTarget. Nello specifico, l'opzione capture viene utilizzata come parte della chiave durante la registrazione di un listener. Qualsiasi singolo listener può essere aggiunto una volta con capture = false e una volta con capture = true.
function handler(event) {}
const target = new EventTarget();
target.addEventListener('foo', handler, { capture: true }); // first
target.addEventListener('foo', handler, { capture: false }); // second
// Rimuove la seconda istanza di handler
target.removeEventListener('foo', handler);
// Rimuove la prima istanza di handler
target.removeEventListener('foo', handler, { capture: true });eventTarget.dispatchEvent(event)
Aggiunto in: v14.5.0
event<Event>- Restituisce: <boolean>
truese il valore dell'attributocancelabledell'evento è false o il suo metodopreventDefault()non è stato invocato, altrimentifalse.
Inoltra l'event all'elenco di gestori per event.type.
I listener di eventi registrati vengono invocati sincronicamente nell'ordine in cui sono stati registrati.
eventTarget.removeEventListener(type, listener[, options])
Aggiunto in: v14.5.0
type<string>listener<Function> | <EventListener>options<Object>capture<boolean>
Rimuove il listener dall'elenco dei gestori per l'type dell'evento.
Classe: CustomEvent
[Cronologia]
| Versione | Modifiche |
|---|---|
| v23.0.0 | Non più sperimentale. |
| v22.1.0, v20.13.0 | CustomEvent è ora stabile. |
| v19.0.0 | Non più dietro il flag CLI --experimental-global-customevent. |
| v18.7.0, v16.17.0 | Aggiunto in: v18.7.0, v16.17.0 |
[Stabile: 2 - Stabile]
Stabile: 2 Stabilità: 2 - Stabile
- Estende: <Event>
L'oggetto CustomEvent è un adattamento della CustomEvent Web API. Le istanze vengono create internamente da Node.js.
event.detail
[Cronologia]
| Versione | Modifiche |
|---|---|
| v22.1.0, v20.13.0 | CustomEvent è ora stabile. |
| v18.7.0, v16.17.0 | Aggiunto in: v18.7.0, v16.17.0 |
[Stabile: 2 - Stabile]
Stabile: 2 Stabilità: 2 - Stabile
- Tipo: <any> Restituisce dati personalizzati passati durante l'inizializzazione.
Sola lettura.
Classe: NodeEventTarget
Aggiunto in: v14.5.0
- Estende: <EventTarget>
NodeEventTarget è un'estensione specifica di Node.js per EventTarget che emula un sottoinsieme dell'API EventEmitter.
nodeEventTarget.addListener(type, listener)
Aggiunto in: v14.5.0
type<stringa>listener<Funzione> | <EventListener>- Restituisce: <EventTarget> questo
Estensione specifica di Node.js alla classe EventTarget che emula l'equivalente API EventEmitter. L'unica differenza tra addListener() e addEventListener() è che addListener() restituirà un riferimento a EventTarget.
nodeEventTarget.emit(type, arg)
Aggiunto in: v15.2.0
type<stringa>arg<qualsiasi>- Restituisce: <booleano>
truese esistono listener di eventi registrati per iltype, altrimentifalse.
Estensione specifica di Node.js alla classe EventTarget che invia l'arg all'elenco di gestori per type.
nodeEventTarget.eventNames()
Aggiunto in: v14.5.0
- Restituisce: <stringa[]>
Estensione specifica di Node.js alla classe EventTarget che restituisce un array di nomi type di eventi per i quali sono registrati i listener di eventi.
nodeEventTarget.listenerCount(type)
Aggiunto in: v14.5.0
Estensione specifica di Node.js alla classe EventTarget che restituisce il numero di listener di eventi registrati per il type.
nodeEventTarget.setMaxListeners(n)
Aggiunto in: v14.5.0
n<number>
Estensione specifica di Node.js alla classe EventTarget che imposta il numero massimo di listener di eventi come n.
nodeEventTarget.getMaxListeners()
Aggiunto in: v14.5.0
- Restituisce: <number>
Estensione specifica di Node.js alla classe EventTarget che restituisce il numero massimo di listener di eventi.
nodeEventTarget.off(type, listener[, options])
Aggiunto in: v14.5.0
type<string>listener<Function> | <EventListener>options<Object>capture<boolean>
Restituisce: <EventTarget> this
Alias specifico di Node.js per eventTarget.removeEventListener().
nodeEventTarget.on(type, listener)
Aggiunto in: v14.5.0
type<string>listener<Function> | <EventListener>- Restituisce: <EventTarget> this
Alias specifico di Node.js per eventTarget.addEventListener().
nodeEventTarget.once(type, listener)
Aggiunto in: v14.5.0
type<string>listener<Function> | <EventListener>- Restituisce: <EventTarget> this
Estensione specifica di Node.js alla classe EventTarget che aggiunge un listener once per il dato type di evento. Questo è equivalente a chiamare on con l'opzione once impostata su true.
nodeEventTarget.removeAllListeners([type])
Aggiunto in: v14.5.0
type<stringa>- Restituisce: <EventTarget> this
Estensione specifica di Node.js alla classe EventTarget. Se type è specificato, rimuove tutti i listener registrati per type, altrimenti rimuove tutti i listener registrati.
nodeEventTarget.removeListener(type, listener[, options])
Aggiunto in: v14.5.0
type<stringa>listener<Funzione> | <EventListener>options<Oggetto>capture<booleano>
Restituisce: <EventTarget> this
Estensione specifica di Node.js alla classe EventTarget che rimuove il listener per il dato type. L'unica differenza tra removeListener() e removeEventListener() è che removeListener() restituirà un riferimento a EventTarget.