Skip to content

Eventos

[Estable: 2 - Estable]

Estable: 2 Estabilidad: 2 - Estable

Código Fuente: lib/events.js

Gran parte de la API principal de Node.js está construida alrededor de una arquitectura idiomática asíncrona impulsada por eventos en la que ciertos tipos de objetos (llamados "emisores") emiten eventos nombrados que hacen que se llamen objetos Function ("oyentes").

Por ejemplo: un objeto net.Server emite un evento cada vez que un par se conecta a él; un fs.ReadStream emite un evento cuando se abre el archivo; un stream emite un evento cada vez que hay datos disponibles para ser leídos.

Todos los objetos que emiten eventos son instancias de la clase EventEmitter. Estos objetos exponen una función eventEmitter.on() que permite adjuntar una o más funciones a eventos nombrados emitidos por el objeto. Por lo general, los nombres de los eventos son cadenas con formato camelCase, pero se puede usar cualquier clave de propiedad de JavaScript válida.

Cuando el objeto EventEmitter emite un evento, todas las funciones adjuntas a ese evento específico se llaman síncronamente. Cualquier valor devuelto por los oyentes llamados es ignorado y descartado.

El siguiente ejemplo muestra una instancia simple de EventEmitter con un solo oyente. El método eventEmitter.on() se utiliza para registrar oyentes, mientras que el método eventEmitter.emit() se utiliza para activar el evento.

js
import { EventEmitter } from 'node:events'

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
myEmitter.on('event', () => {
  console.log('¡Ocurrió un evento!')
})
myEmitter.emit('event')
js
const EventEmitter = require('node:events')

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
myEmitter.on('event', () => {
  console.log('¡Ocurrió un evento!')
})
myEmitter.emit('event')

Pasar argumentos y this a los listeners

El método eventEmitter.emit() permite pasar un conjunto arbitrario de argumentos a las funciones de listener. Ten en cuenta que cuando se llama a una función de listener ordinaria, la palabra clave estándar this se establece intencionalmente para hacer referencia a la instancia de EventEmitter a la que está adjunto el listener.

js
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)
  // Imprime:
  //   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')
js
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)
  // Imprime:
  //   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')

Es posible usar Funciones Flecha ES6 como listeners, sin embargo, al hacerlo, la palabra clave this ya no hará referencia a la instancia de EventEmitter:

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  console.log(a, b, this)
  // Imprime: a b undefined
})
myEmitter.emit('event', 'a', 'b')
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  console.log(a, b, this)
  // Imprime: a b {}
})
myEmitter.emit('event', 'a', 'b')

Asíncrono vs. síncrono

El EventEmitter llama a todos los listeners de forma síncrona en el orden en que fueron registrados. Esto asegura la secuencia adecuada de los eventos y ayuda a evitar condiciones de carrera y errores lógicos. Cuando es apropiado, las funciones de listener pueden cambiar a un modo de operación asíncrono usando los métodos setImmediate() o process.nextTick():

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('esto sucede asíncronamente')
  })
})
myEmitter.emit('event', 'a', 'b')
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('esto sucede asíncronamente')
  })
})
myEmitter.emit('event', 'a', 'b')

Manejar eventos solo una vez

Cuando un listener se registra usando el método eventEmitter.on(), ese listener es invocado cada vez que se emite el evento nombrado.

js
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')
// Imprime: 1
myEmitter.emit('event')
// Imprime: 2
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
let m = 0
myEmitter.on('event', () => {
  console.log(++m)
})
myEmitter.emit('event')
// Imprime: 1
myEmitter.emit('event')
// Imprime: 2

Usando el método eventEmitter.once(), es posible registrar un listener que se llama como máximo una vez para un evento en particular. Una vez que se emite el evento, el listener se da de baja y luego se llama.

js
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')
// Imprime: 1
myEmitter.emit('event')
// Ignorado
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
let m = 0
myEmitter.once('event', () => {
  console.log(++m)
})
myEmitter.emit('event')
// Imprime: 1
myEmitter.emit('event')
// Ignorado

Eventos de error

Cuando ocurre un error dentro de una instancia de EventEmitter, la acción típica es que se emita un evento 'error'. Estos se tratan como casos especiales dentro de Node.js.

Si un EventEmitter no tiene al menos un oyente registrado para el evento 'error', y se emite un evento 'error', el error se lanza, se imprime un rastreo de pila y el proceso de Node.js sale.

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.emit('error', new Error('¡Ups!'))
// Lanza y bloquea Node.js
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.emit('error', new Error('¡Ups!'))
// Lanza y bloquea Node.js

Para evitar que el proceso de Node.js se bloquee, se puede usar el módulo domain. (Sin embargo, tenga en cuenta que el módulo node:domain está obsoleto).

Como práctica recomendada, siempre se deben agregar oyentes para los eventos 'error'.

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('error', err => {
  console.error('¡Ups! hubo un error')
})
myEmitter.emit('error', new Error('¡Ups!'))
// Imprime: ¡Ups! hubo un error
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('error', err => {
  console.error('¡Ups! hubo un error')
})
myEmitter.emit('error', new Error('¡Ups!'))
// Imprime: ¡Ups! hubo un error

Es posible monitorear los eventos 'error' sin consumir el error emitido instalando un oyente usando el símbolo events.errorMonitor.

js
import { EventEmitter, errorMonitor } from 'node:events'

const myEmitter = new EventEmitter()
myEmitter.on(errorMonitor, err => {
  MyMonitoringTool.log(err)
})
myEmitter.emit('error', new Error('¡Ups!'))
// Aún lanza y bloquea Node.js
js
const { EventEmitter, errorMonitor } = require('node:events')

const myEmitter = new EventEmitter()
myEmitter.on(errorMonitor, err => {
  MyMonitoringTool.log(err)
})
myEmitter.emit('error', new Error('¡Ups!'))
// Aún lanza y bloquea Node.js

Capturar rechazos de promesas

Usar funciones async con manejadores de eventos es problemático, porque puede llevar a un rechazo no manejado en caso de una excepción lanzada:

js
import { EventEmitter } from 'node:events'
const ee = new EventEmitter()
ee.on('something', async value => {
  throw new Error('kaboom')
})
js
const EventEmitter = require('node:events')
const ee = new EventEmitter()
ee.on('something', async value => {
  throw new Error('kaboom')
})

La opción captureRejections en el constructor EventEmitter o el cambio de configuración global cambian este comportamiento, instalando un manejador .then(undefined, handler) en la Promise. Este manejador enruta la excepción de forma asíncrona al método Symbol.for('nodejs.rejection') si existe uno, o al manejador de eventos 'error' si no hay ninguno.

js
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
js
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

Configurar events.captureRejections = true cambiará el valor predeterminado para todas las nuevas instancias de EventEmitter.

js
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)
js
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)

Los eventos 'error' que son generados por el comportamiento captureRejections no tienen un manejador catch para evitar bucles de error infinitos: la recomendación es no usar funciones async como manejadores de eventos 'error'.

Clase: EventEmitter

[Historial]

VersiónCambios
v13.4.0, v12.16.0Se añadió la opción captureRejections.
v0.1.26Añadido en: v0.1.26

La clase EventEmitter es definida y expuesta por el módulo node:events:

js
import { EventEmitter } from 'node:events'
js
const EventEmitter = require('node:events')

Todos los EventEmitter emiten el evento 'newListener' cuando se añaden nuevos listeners y 'removeListener' cuando se eliminan listeners existentes.

Soporta la siguiente opción:

Evento: 'newListener'

Añadido en: v0.1.26

La instancia de EventEmitter emitirá su propio evento 'newListener' antes de que un listener sea añadido a su array interno de listeners.

Los listeners registrados para el evento 'newListener' reciben el nombre del evento y una referencia al listener que se está añadiendo.

El hecho de que el evento se active antes de añadir el listener tiene un efecto secundario sutil pero importante: cualquier listener adicional registrado para el mismo nombre dentro del callback de 'newListener' se inserta antes del listener que está en proceso de ser añadido.

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
// Solo hacer esto una vez para no entrar en un bucle infinito
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Inserta un nuevo listener al frente
    myEmitter.on('event', () => {
      console.log('B')
    })
  }
})
myEmitter.on('event', () => {
  console.log('A')
})
myEmitter.emit('event')
// Imprime:
//   B
//   A
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
// Solo hacer esto una vez para no entrar en un bucle infinito
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Inserta un nuevo listener al frente
    myEmitter.on('event', () => {
      console.log('B')
    })
  }
})
myEmitter.on('event', () => {
  console.log('A')
})
myEmitter.emit('event')
// Imprime:
//   B
//   A

Evento: 'removeListener'

[Historial]

VersiónCambios
v6.1.0, v4.7.0Para los listeners adjuntos usando .once(), el argumento listener ahora produce la función listener original.
v0.9.3Añadido en: v0.9.3

El evento 'removeListener' se emite después de que se elimina el listener.

emitter.addListener(eventName, listener)

Añadido en: v0.1.26

Alias para emitter.on(eventName, listener).

emitter.emit(eventName[, ...args])

Agregado en: v0.1.26

Llama sincrónicamente a cada uno de los listeners registrados para el evento llamado eventName, en el orden en que fueron registrados, pasando los argumentos suministrados a cada uno.

Devuelve true si el evento tenía listeners, false en caso contrario.

js
import { EventEmitter } from 'node:events'
const myEmitter = new EventEmitter()

// Primer listener
myEmitter.on('event', function firstListener() {
  console.log('¡Hola! primer listener')
})
// Segundo listener
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`evento con parámetros ${arg1}, ${arg2} en el segundo listener`)
})
// Tercer listener
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ')
  console.log(`evento con parámetros ${parameters} en el tercer listener`)
})

console.log(myEmitter.listeners('event'))

myEmitter.emit('event', 1, 2, 3, 4, 5)

// Imprime:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// ¡Hola! primer listener
// evento con parámetros 1, 2 en el segundo listener
// evento con parámetros 1, 2, 3, 4, 5 en el tercer listener
js
const EventEmitter = require('node:events')
const myEmitter = new EventEmitter()

// Primer listener
myEmitter.on('event', function firstListener() {
  console.log('¡Hola! primer listener')
})
// Segundo listener
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`evento con parámetros ${arg1}, ${arg2} en el segundo listener`)
})
// Tercer listener
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ')
  console.log(`evento con parámetros ${parameters} en el tercer listener`)
})

console.log(myEmitter.listeners('event'))

myEmitter.emit('event', 1, 2, 3, 4, 5)

// Imprime:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// ¡Hola! primer listener
// evento con parámetros 1, 2 en el segundo listener
// evento con parámetros 1, 2, 3, 4, 5 en el tercer listener

emitter.eventNames()

Agregado en: v6.0.0

Devuelve un array que enumera los eventos para los que el emisor ha registrado listeners. Los valores en el array son cadenas o Symbols.

js
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())
// Imprime: [ 'foo', 'bar', Symbol(symbol) ]
js
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())
// Imprime: [ 'foo', 'bar', Symbol(symbol) ]

emitter.getMaxListeners()

Agregado en: v1.0.0

Devuelve el valor máximo actual de listeners para el EventEmitter que se establece mediante emitter.setMaxListeners(n) o que por defecto es events.defaultMaxListeners.

emitter.listenerCount(eventName[, listener])

[Historial]

VersiónCambios
v19.8.0, v18.16.0Se agregó el argumento listener.
v3.2.0Se agregó en: v3.2.0

Devuelve el número de listeners que escuchan el evento llamado eventName. Si se proporciona listener, devolverá cuántas veces se encuentra el listener en la lista de listeners del evento.

emitter.listeners(eventName)

[Historial]

VersiónCambios
v7.0.0Para los listeners adjuntos utilizando .once(), ahora devuelve los listeners originales en lugar de las funciones de envoltura.
v0.1.26Se agregó en: v0.1.26

Devuelve una copia del array de listeners para el evento llamado eventName.

js
server.on('connection', stream => {
  console.log('¡alguien se conectó!')
})
console.log(util.inspect(server.listeners('connection')))
// Imprime: [ [Function] ]

emitter.off(eventName, listener)

Agregado en: v10.0.0

Alias para emitter.removeListener().

emitter.on(eventName, listener)

Agregado en: v0.1.101

Agrega la función listener al final del array de listeners para el evento llamado eventName. No se realizan comprobaciones para ver si el listener ya ha sido agregado. Múltiples llamadas pasando la misma combinación de eventName y listener resultarán en que el listener sea agregado, y llamado, múltiples veces.

js
server.on('connection', stream => {
  console.log('¡alguien se conectó!')
})

Devuelve una referencia al EventEmitter, para que las llamadas puedan ser encadenadas.

Por defecto, los listeners de eventos son invocados en el orden en que son agregados. El método emitter.prependListener() puede ser usado como una alternativa para agregar el listener de evento al principio del array de listeners.

js
import { EventEmitter } from 'node:events'
const myEE = new EventEmitter()
myEE.on('foo', () => console.log('a'))
myEE.prependListener('foo', () => console.log('b'))
myEE.emit('foo')
// Imprime:
//   b
//   a
js
const EventEmitter = require('node:events')
const myEE = new EventEmitter()
myEE.on('foo', () => console.log('a'))
myEE.prependListener('foo', () => console.log('b'))
myEE.emit('foo')
// Imprime:
//   b
//   a

emitter.once(eventName, listener)

Añadido en: v0.3.0

Añade una función listener de una sola vez para el evento llamado eventName. La próxima vez que se active eventName, este listener se elimina y luego se invoca.

js
server.once('connection', stream => {
  console.log('¡Ah, tenemos nuestro primer usuario!')
})

Devuelve una referencia a EventEmitter, para que las llamadas se puedan encadenar.

Por defecto, los listeners de eventos se invocan en el orden en que se añaden. El método emitter.prependOnceListener() se puede usar como alternativa para añadir el listener de eventos al principio del array de listeners.

js
import { EventEmitter } from 'node:events'
const myEE = new EventEmitter()
myEE.once('foo', () => console.log('a'))
myEE.prependOnceListener('foo', () => console.log('b'))
myEE.emit('foo')
// Imprime:
//   b
//   a
js
const EventEmitter = require('node:events')
const myEE = new EventEmitter()
myEE.once('foo', () => console.log('a'))
myEE.prependOnceListener('foo', () => console.log('b'))
myEE.emit('foo')
// Imprime:
//   b
//   a

emitter.prependListener(eventName, listener)

Agregado en: v6.0.0

Agrega la función listener al principio del array de listeners para el evento llamado eventName. No se realizan comprobaciones para ver si el listener ya ha sido añadido. Múltiples llamadas que pasan la misma combinación de eventName y listener resultarán en que el listener se añada, y se llame, varias veces.

js
server.prependListener('connection', stream => {
  console.log('¡alguien se ha conectado!')
})

Devuelve una referencia al EventEmitter, de modo que las llamadas se puedan encadenar.

emitter.prependOnceListener(eventName, listener)

Agregado en: v6.0.0

Agrega una función listener de una sola vez para el evento llamado eventName al principio del array de listeners. La próxima vez que se active eventName, este listener se elimina y luego se invoca.

js
server.prependOnceListener('connection', stream => {
  console.log('¡Ah, tenemos nuestro primer usuario!')
})

Devuelve una referencia a EventEmitter, para que las llamadas puedan encadenarse.

emitter.removeAllListeners([eventName])

Agregado en: v0.1.26

Elimina todos los listeners, o aquellos del eventName especificado.

Es una mala práctica eliminar listeners agregados en otro lugar del código, particularmente cuando la instancia de EventEmitter fue creada por algún otro componente o módulo (p. ej., sockets o flujos de archivos).

Devuelve una referencia a EventEmitter, para que las llamadas puedan encadenarse.

emitter.removeListener(eventName, listener)

Agregado en: v0.1.26

Elimina el listener especificado del arreglo de listeners para el evento llamado eventName.

js
const callback = stream => {
  console.log('¡alguien se conectó!')
}
server.on('connection', callback)
// ...
server.removeListener('connection', callback)

removeListener() eliminará, como máximo, una instancia de un listener del arreglo de listeners. Si algún listener se ha añadido varias veces al arreglo de listeners para el eventName especificado, entonces removeListener() debe llamarse varias veces para eliminar cada instancia.

Una vez que se emite un evento, todos los listeners adjuntos a él en el momento de la emisión se llaman en orden. Esto implica que cualquier llamada a removeListener() o removeAllListeners() después de la emisión y antes de que el último listener termine la ejecución no los eliminará de emit() en progreso. Los eventos posteriores se comportan como se espera.

js
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 elimina el listener callbackB pero todavía será llamado.
// Arreglo interno de listeners al momento de emitir [callbackA, callbackB]
myEmitter.emit('event')
// Imprime:
//   A
//   B

// callbackB ahora está eliminado.
// Arreglo interno de listeners [callbackA]
myEmitter.emit('event')
// Imprime:
//   A
js
const 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 elimina el listener callbackB pero todavía será llamado.
// Arreglo interno de listeners al momento de emitir [callbackA, callbackB]
myEmitter.emit('event')
// Imprime:
//   A
//   B

// callbackB ahora está eliminado.
// Arreglo interno de listeners [callbackA]
myEmitter.emit('event')
// Imprime:
//   A

Debido a que los listeners se gestionan utilizando un arreglo interno, llamar a esto cambiará los índices de posición de cualquier listener registrado después del listener que se está eliminando. Esto no afectará el orden en que se llaman los listeners, pero significa que cualquier copia del arreglo de listeners devuelto por el método emitter.listeners() deberá ser recreada.

Cuando se ha añadido una única función como controlador varias veces para un solo evento (como en el ejemplo siguiente), removeListener() eliminará la instancia añadida más recientemente. En el ejemplo se elimina el listener once('ping'):

js
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')
js
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')

Devuelve una referencia al EventEmitter, para que las llamadas se puedan encadenar.

emitter.setMaxListeners(n)

Agregado en: v0.3.5

De forma predeterminada, los EventEmitter imprimirán una advertencia si se agregan más de 10 listeners para un evento en particular. Este es un valor predeterminado útil que ayuda a encontrar fugas de memoria. El método emitter.setMaxListeners() permite modificar el límite para esta instancia específica de EventEmitter. El valor se puede establecer en Infinity (o 0) para indicar un número ilimitado de listeners.

Devuelve una referencia al EventEmitter, de modo que las llamadas se puedan encadenar.

emitter.rawListeners(eventName)

Agregado en: v9.4.0

Devuelve una copia del array de listeners para el evento llamado eventName, incluyendo cualquier envoltorio (como los creados por .once()).

js
import { EventEmitter } from 'node:events'
const emitter = new EventEmitter()
emitter.once('log', () => console.log('log once'))

// Devuelve un nuevo array con una función `onceWrapper` que tiene una propiedad
// `listener` que contiene el listener original vinculado anteriormente
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]

// Imprime "log once" en la consola y no desvincula el evento `once`
logFnWrapper.listener()

// Imprime "log once" en la consola y elimina el listener
logFnWrapper()

emitter.on('log', () => console.log('log persistently'))
// Devolverá un nuevo array con una única función vinculada por `.on()` anteriormente
const newListeners = emitter.rawListeners('log')

// Imprime "log persistently" dos veces
newListeners[0]()
emitter.emit('log')
js
const EventEmitter = require('node:events')
const emitter = new EventEmitter()
emitter.once('log', () => console.log('log once'))

// Devuelve un nuevo array con una función `onceWrapper` que tiene una propiedad
// `listener` que contiene el listener original vinculado anteriormente
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]

// Imprime "log once" en la consola y no desvincula el evento `once`
logFnWrapper.listener()

// Imprime "log once" en la consola y elimina el listener
logFnWrapper()

emitter.on('log', () => console.log('log persistently'))
// Devolverá un nuevo array con una única función vinculada por `.on()` anteriormente
const newListeners = emitter.rawListeners('log')

// Imprime "log persistently" dos veces
newListeners[0]()
emitter.emit('log')

emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])

[Historial]

VersiónCambios
v17.4.0, v16.14.0Ya no es experimental.
v13.4.0, v12.16.0Añadido en: v13.4.0, v12.16.0

El método Symbol.for('nodejs.rejection') se llama en caso de que ocurra un rechazo de promesa al emitir un evento y captureRejections esté habilitado en el emisor. Es posible usar events.captureRejectionSymbol en lugar de Symbol.for('nodejs.rejection').

js
import { EventEmitter, captureRejectionSymbol } from 'node:events'

class MyClass extends EventEmitter {
  constructor() {
    super({ captureRejections: true })
  }

  [captureRejectionSymbol](err, event, ...args) {
    console.log('se produjo un rechazo para', event, 'con', err, ...args)
    this.destroy(err)
  }

  destroy(err) {
    // Destruir el recurso aquí.
  }
}
js
const { EventEmitter, captureRejectionSymbol } = require('node:events')

class MyClass extends EventEmitter {
  constructor() {
    super({ captureRejections: true })
  }

  [captureRejectionSymbol](err, event, ...args) {
    console.log('se produjo un rechazo para', event, 'con', err, ...args)
    this.destroy(err)
  }

  destroy(err) {
    // Destruir el recurso aquí.
  }
}

events.defaultMaxListeners

Agregado en: v0.11.2

De forma predeterminada, se puede registrar un máximo de 10 listeners para cualquier evento individual. Este límite se puede cambiar para instancias individuales de EventEmitter utilizando el método emitter.setMaxListeners(n). Para cambiar el valor predeterminado para todas las instancias de EventEmitter, se puede utilizar la propiedad events.defaultMaxListeners. Si este valor no es un número positivo, se lanza un RangeError.

Tenga cuidado al establecer events.defaultMaxListeners porque el cambio afecta a todas las instancias de EventEmitter, incluidas las que se crearon antes de que se realizara el cambio. Sin embargo, llamar a emitter.setMaxListeners(n) sigue teniendo precedencia sobre events.defaultMaxListeners.

Este no es un límite estricto. La instancia de EventEmitter permitirá que se agreguen más listeners, pero generará una advertencia de seguimiento en stderr que indica que se ha detectado una "posible fuga de memoria de EventEmitter". Para cualquier EventEmitter individual, los métodos emitter.getMaxListeners() y emitter.setMaxListeners() se pueden utilizar para evitar temporalmente esta advertencia:

defaultMaxListeners no tiene efecto en las instancias de AbortSignal. Si bien todavía es posible utilizar emitter.setMaxListeners(n) para establecer un límite de advertencia para instancias individuales de AbortSignal, de forma predeterminada las instancias de AbortSignal no generarán ninguna advertencia.

js
import { EventEmitter } from 'node:events'
const emitter = new EventEmitter()
emitter.setMaxListeners(emitter.getMaxListeners() + 1)
emitter.once('event', () => {
  // do stuff
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0))
})
js
const EventEmitter = require('node:events')
const emitter = new EventEmitter()
emitter.setMaxListeners(emitter.getMaxListeners() + 1)
emitter.once('event', () => {
  // do stuff
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0))
})

El indicador de línea de comandos --trace-warnings se puede usar para mostrar el rastreo de la pila de dichas advertencias.

La advertencia emitida se puede inspeccionar con process.on('warning') y tendrá las propiedades adicionales emitter, type y count, que hacen referencia a la instancia del emisor de eventos, el nombre del evento y el número de listeners adjuntos, respectivamente. Su propiedad name se establece en 'MaxListenersExceededWarning'.

events.errorMonitor

Agregado en: v13.6.0, v12.17.0

Este símbolo se utilizará para instalar un listener solo para monitorear eventos 'error'. Los listeners instalados usando este símbolo se llaman antes de que se llamen los listeners regulares 'error'.

La instalación de un listener utilizando este símbolo no cambia el comportamiento una vez que se emite un evento 'error'. Por lo tanto, el proceso aún fallará si no se instala ningún listener regular 'error'.

events.getEventListeners(emitterOrTarget, eventName)

Agregado en: v15.2.0, v14.17.0

Devuelve una copia de la matriz de listeners para el evento llamado eventName.

Para los EventEmitter, esto se comporta exactamente igual que llamar a .listeners en el emisor.

Para EventTarget, esta es la única forma de obtener los listeners de eventos para el objetivo del evento. Esto es útil para fines de depuración y diagnóstico.

js
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] ]
}
js
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)

Agregado en: v19.9.0, v18.17.0

Devuelve la cantidad máxima de listeners establecida actualmente.

Para EventEmitters, esto se comporta exactamente igual que llamar a .getMaxListeners en el emisor.

Para EventTargets, esta es la única forma de obtener el máximo de listeners de eventos para el target de eventos. Si el número de manejadores de eventos en un solo EventTarget excede el máximo establecido, el EventTarget imprimirá una advertencia.

js
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
}
js
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(emisor, nombre[, opciones])

[Historial]

VersiónCambios
v15.0.0Ahora se soporta la opción signal.
v11.13.0, v10.16.0Añadido en: v11.13.0, v10.16.0

Crea una Promise que se cumple cuando el EventEmitter emite el evento dado o que se rechaza si el EventEmitter emite 'error' mientras espera. La Promise se resolverá con un array de todos los argumentos emitidos al evento dado.

Este método es intencionalmente genérico y funciona con la interfaz EventTarget de la plataforma web, que no tiene semántica especial para el evento 'error' y no escucha al evento 'error'.

js
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)
}
js
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()

El manejo especial del evento 'error' solo se usa cuando events.once() se usa para esperar otro evento. Si events.once() se usa para esperar el propio evento 'error', entonces se trata como cualquier otro tipo de evento sin manejo especial:

js
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'))

// Imprime: ok boom
js
const { 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'))

// Imprime: ok boom

Se puede usar un <AbortSignal> para cancelar la espera del evento:

js
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() // Imprime: Waiting for the event was canceled!
js
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() // Imprime: Waiting for the event was canceled!

Esperando múltiples eventos emitidos en process.nextTick()

Existe un caso límite que vale la pena señalar al usar la función events.once() para esperar múltiples eventos emitidos en el mismo lote de operaciones de process.nextTick(), o cada vez que se emiten múltiples eventos de forma síncrona. Específicamente, debido a que la cola process.nextTick() se vacía antes de la cola de microtareas Promise, y debido a que EventEmitter emite todos los eventos de forma síncrona, es posible que events.once() pierda un evento.

js
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')

  // Esta Promise nunca se resolverá porque el evento 'foo' ya se
  // habrá emitido antes de que se cree la Promise.
  await once(myEE, 'foo')
  console.log('foo')
}

process.nextTick(() => {
  myEE.emit('bar')
  myEE.emit('foo')
})

foo().then(() => console.log('done'))
js
const { EventEmitter, once } = require('node:events')

const myEE = new EventEmitter()

async function foo() {
  await once(myEE, 'bar')
  console.log('bar')

  // Esta Promise nunca se resolverá porque el evento 'foo' ya se
  // habrá emitido antes de que se cree la Promise.
  await once(myEE, 'foo')
  console.log('foo')
}

process.nextTick(() => {
  myEE.emit('bar')
  myEE.emit('foo')
})

foo().then(() => console.log('done'))

Para capturar ambos eventos, crea cada una de las Promesas antes de esperar cualquiera de ellas, entonces se vuelve posible usar Promise.all(), Promise.race(), o Promise.allSettled():

js
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'))
js
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

[Historial]

VersiónCambios
v17.4.0, v16.14.0Ya no es experimental.
v13.4.0, v12.16.0Añadido en: v13.4.0, v12.16.0

Valor: <boolean>

Cambia la opción captureRejections predeterminada en todos los nuevos objetos EventEmitter.

events.captureRejectionSymbol

[Historial]

VersiónCambios
v17.4.0, v16.14.0Ya no es experimental.
v13.4.0, v12.16.0Añadido en: v13.4.0, v12.16.0

Valor: Symbol.for('nodejs.rejection')

Mira cómo escribir un manejador de rechazos personalizado.

events.listenerCount(emitter, eventName)

Añadido en: v0.9.12

Obsoleto desde: v3.2.0

[Estable: 0 - Obsoleto]

Estable: 0 Estabilidad: 0 - Obsoleto: Use emitter.listenerCount() en su lugar.

Un método de clase que devuelve el número de listeners para el eventName dado registrado en el emitter dado.

js
import { EventEmitter, listenerCount } from 'node:events'

const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// Imprime: 2
js
const { EventEmitter, listenerCount } = require('node:events')

const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// Imprime: 2

events.on(emisor, nombreEvento[, opciones])

[Historial]

VersiónCambios
v22.0.0, v20.13.0Soporte para opciones highWaterMark y lowWaterMark, por consistencia. Las opciones antiguas siguen siendo compatibles.
v20.0.0Ahora se admiten las opciones close, highWatermark y lowWatermark.
v13.6.0, v12.16.0Añadido en: v13.6.0, v12.16.0
  • emisor <EventEmitter>

  • nombreEvento <string> | <symbol> El nombre del evento que se está escuchando

  • opciones <Object>

    • signal <AbortSignal> Se puede utilizar para cancelar eventos en espera.
    • close - <string[]> Nombres de los eventos que finalizarán la iteración.
    • highWaterMark - <integer> Predeterminado: Number.MAX_SAFE_INTEGER. La marca de agua alta. El emisor se pausa cada vez que el tamaño de los eventos almacenados en búfer es mayor que ella. Solo se admite en emisores que implementan los métodos pause() y resume().
    • lowWaterMark - <integer> Predeterminado: 1. La marca de agua baja. El emisor se reanuda cada vez que el tamaño de los eventos almacenados en búfer es inferior a ella. Solo se admite en emisores que implementan los métodos pause() y resume().
  • Devuelve: <AsyncIterator> que itera los eventos nombreEvento emitidos por el emisor

js
import { on, EventEmitter } from 'node:events'
import process from 'node:process'

const ee = new EventEmitter()

// Emitir más tarde
process.nextTick(() => {
  ee.emit('foo', 'bar')
  ee.emit('foo', 42)
})

for await (const evento of on(ee, 'foo')) {
  // La ejecución de este bloque interno es síncrona y procesa un
  // evento a la vez (incluso con await). No usar si se requiere
  // ejecución concurrente.
  console.log(evento) // Imprime ['bar'] [42]
}
// Inalcanzable aquí
js
const { on, EventEmitter } = require('node:events')

;(async () => {
  const ee = new EventEmitter()

  // Emitir más tarde
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const evento of on(ee, 'foo')) {
    // La ejecución de este bloque interno es síncrona y procesa un
    // evento a la vez (incluso con await). No usar si se requiere
    // ejecución concurrente.
    console.log(evento) // Imprime ['bar'] [42]
  }
  // Inalcanzable aquí
})()

Devuelve un AsyncIterator que itera los eventos nombreEvento. Lanzará un error si el EventEmitter emite 'error'. Elimina todos los listeners al salir del bucle. El valor devuelto por cada iteración es un array compuesto por los argumentos del evento emitido.

Se puede utilizar un <AbortSignal> para cancelar la espera de eventos:

js
import { on, EventEmitter } from 'node:events'
import process from 'node:process'

const ac = new AbortController()

;(async () => {
  const ee = new EventEmitter()

  // Emitir más tarde
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const evento of on(ee, 'foo', { signal: ac.signal })) {
    // La ejecución de este bloque interno es síncrona y procesa un
    // evento a la vez (incluso con await). No usar si se requiere
    // ejecución concurrente.
    console.log(evento) // Imprime ['bar'] [42]
  }
  // Inalcanzable aquí
})()

process.nextTick(() => ac.abort())
js
const { on, EventEmitter } = require('node:events')

const ac = new AbortController()

;(async () => {
  const ee = new EventEmitter()

  // Emitir más tarde
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const evento of on(ee, 'foo', { signal: ac.signal })) {
    // La ejecución de este bloque interno es síncrona y procesa un
    // evento a la vez (incluso con await). No usar si se requiere
    // ejecución concurrente.
    console.log(evento) // Imprime ['bar'] [42]
  }
  // Inalcanzable aquí
})()

process.nextTick(() => ac.abort())

events.setMaxListeners(n[, ...eventTargets])

Agregado en: v15.4.0

js
import { setMaxListeners, EventEmitter } from 'node:events'

const target = new EventTarget()
const emitter = new EventEmitter()

setMaxListeners(5, target, emitter)
js
const { setMaxListeners, EventEmitter } = require('node:events')

const target = new EventTarget()
const emitter = new EventEmitter()

setMaxListeners(5, target, emitter)

events.addAbortListener(signal, listener)

Añadido en: v20.5.0, v18.18.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1 - Experimental

Escucha una vez el evento abort en la señal proporcionada.

Escuchar el evento abort en señales de aborto no es seguro y puede provocar fugas de recursos, ya que otro tercero con la señal puede llamar a e.stopImmediatePropagation(). Desafortunadamente, Node.js no puede cambiar esto ya que violaría el estándar web. Además, la API original facilita olvidar eliminar los listeners.

Esta API permite utilizar de forma segura AbortSignals en las APIs de Node.js al resolver estos dos problemas, escuchando el evento de tal manera que stopImmediatePropagation no impida que el listener se ejecute.

Devuelve un disposable para que se pueda dar de baja más fácilmente.

js
const { addAbortListener } = require('node:events')

function example(signal) {
  let disposable
  try {
    signal.addEventListener('abort', e => e.stopImmediatePropagation())
    disposable = addAbortListener(signal, e => {
      // Hacer algo cuando se aborte la señal.
    })
  } finally {
    disposable?.[Symbol.dispose]()
  }
}
js
import { addAbortListener } from 'node:events'

function example(signal) {
  let disposable
  try {
    signal.addEventListener('abort', e => e.stopImmediatePropagation())
    disposable = addAbortListener(signal, e => {
      // Hacer algo cuando se aborte la señal.
    })
  } finally {
    disposable?.[Symbol.dispose]()
  }
}

Clase: events.EventEmitterAsyncResource extends EventEmitter

Agregado en: v17.4.0, v16.14.0

Integra EventEmitter con <AsyncResource> para EventEmitters que requieren seguimiento asíncrono manual. Específicamente, todos los eventos emitidos por instancias de events.EventEmitterAsyncResource se ejecutarán dentro de su contexto asíncrono.

js
import { EventEmitterAsyncResource, EventEmitter } from 'node:events'
import { notStrictEqual, strictEqual } from 'node:assert'
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks'

// Las herramientas de seguimiento asíncrono identificarán esto como 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' })

// Los listeners de 'foo' se ejecutarán en el contexto asíncrono de EventEmitters.
ee1.on('foo', () => {
  strictEqual(executionAsyncId(), ee1.asyncId)
  strictEqual(triggerAsyncId(), ee1.triggerAsyncId)
})

const ee2 = new EventEmitter()

// Los listeners de 'foo' en EventEmitters ordinarios que no rastrean el contexto asíncrono,
// sin embargo, se ejecutan en el mismo contexto asíncrono que el emit().
ee2.on('foo', () => {
  notStrictEqual(executionAsyncId(), ee2.asyncId)
  notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId)
})

Promise.resolve().then(() => {
  ee1.emit('foo')
  ee2.emit('foo')
})
js
const { EventEmitterAsyncResource, EventEmitter } = require('node:events')
const { notStrictEqual, strictEqual } = require('node:assert')
const { executionAsyncId, triggerAsyncId } = require('node:async_hooks')

// Las herramientas de seguimiento asíncrono identificarán esto como 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' })

// Los listeners de 'foo' se ejecutarán en el contexto asíncrono de EventEmitters.
ee1.on('foo', () => {
  strictEqual(executionAsyncId(), ee1.asyncId)
  strictEqual(triggerAsyncId(), ee1.triggerAsyncId)
})

const ee2 = new EventEmitter()

// Los listeners de 'foo' en EventEmitters ordinarios que no rastrean el contexto asíncrono,
// sin embargo, se ejecutan en el mismo contexto asíncrono que el emit().
ee2.on('foo', () => {
  notStrictEqual(executionAsyncId(), ee2.asyncId)
  notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId)
})

Promise.resolve().then(() => {
  ee1.emit('foo')
  ee2.emit('foo')
})

La clase EventEmitterAsyncResource tiene los mismos métodos y toma las mismas opciones que EventEmitter y AsyncResource mismos.

new events.EventEmitterAsyncResource([opciones])

  • opciones <Objeto>
    • captureRejections <boolean> Habilita la captura automática del rechazo de promesas. Predeterminado: false.
    • name <string> El tipo de evento asíncrono. Predeterminado: new.target.name.
    • triggerAsyncId <number> El ID del contexto de ejecución que creó este evento asíncrono. Predeterminado: executionAsyncId().
    • requireManualDestroy <boolean> Si se establece en true, deshabilita emitDestroy cuando el objeto es recolectado por el recolector de basura. Por lo general, esto no necesita establecerse (incluso si emitDestroy se llama manualmente), a menos que se recupere el asyncId del recurso y se llame a la API sensible emitDestroy con él. Cuando se establece en false, la llamada emitDestroy en la recolección de basura solo tendrá lugar si hay al menos un gancho destroy activo. Predeterminado: false.

eventemitterasyncresource.asyncId

  • Tipo: <número> El asyncId único asignado al recurso.

eventemitterasyncresource.asyncResource

El objeto AsyncResource devuelto tiene una propiedad eventEmitter adicional que proporciona una referencia a este EventEmitterAsyncResource.

eventemitterasyncresource.emitDestroy()

Llama a todos los ganchos destroy. Esto solo debería llamarse una vez. Se generará un error si se llama más de una vez. Esto debe llamarse manualmente. Si se deja que el recurso sea recolectado por el GC, los ganchos destroy nunca serán llamados.

eventemitterasyncresource.triggerAsyncId

  • Tipo: <número> El mismo triggerAsyncId que se pasa al constructor AsyncResource.

API EventTarget y Event

[Historial]

VersiónCambios
v16.0.0Se cambió el manejo de errores de EventTarget.
v15.4.0Ya no es experimental.
v15.0.0Las clases EventTarget y Event ahora están disponibles como globales.
v14.5.0Añadido en: v14.5.0

Los objetos EventTarget y Event son una implementación específica de Node.js de la EventTarget Web API que exponen algunas APIs centrales de Node.js.

js
const target = new EventTarget()

target.addEventListener('foo', event => {
  console.log('¡El evento foo ocurrió!')
})

EventTarget de Node.js vs. EventTarget del DOM

Existen dos diferencias clave entre el EventTarget de Node.js y la EventTarget Web API:

NodeEventTarget vs. EventEmitter

El objeto NodeEventTarget implementa un subconjunto modificado de la API EventEmitter que le permite emular estrechamente un EventEmitter en ciertas situaciones. Un NodeEventTarget no es una instancia de EventEmitter y no se puede utilizar en lugar de un EventEmitter en la mayoría de los casos.

Escucha de eventos

Los escuchas de eventos registrados para un tipo de evento pueden ser funciones de JavaScript u objetos con una propiedad handleEvent cuyo valor sea una función.

En cualquier caso, la función de controlador se invoca con el argumento event que se pasa a la función eventTarget.dispatchEvent().

Se pueden utilizar funciones asíncronas como escuchas de eventos. Si una función de controlador asíncrona rechaza, el rechazo se captura y se maneja como se describe en el manejo de errores de EventTarget.

Un error lanzado por una función de controlador no impide que se invoquen los otros controladores.

El valor de retorno de una función de controlador se ignora.

Los controladores siempre se invocan en el orden en que se agregaron.

Las funciones de controlador pueden mutar el objeto event.

js
function handler1(event) {
  console.log(event.type) // Imprime 'foo'
  event.a = 1
}

async function handler2(event) {
  console.log(event.type) // Imprime 'foo'
  console.log(event.a) // Imprime 1
}

const handler3 = {
  handleEvent(event) {
    console.log(event.type) // Imprime 'foo'
  },
}

const handler4 = {
  async handleEvent(event) {
    console.log(event.type) // Imprime 'foo'
  },
}

const target = new EventTarget()

target.addEventListener('foo', handler1)
target.addEventListener('foo', handler2)
target.addEventListener('foo', handler3)
target.addEventListener('foo', handler4, { once: true })

Manejo de errores en EventTarget

Cuando un receptor de eventos registrado lanza una excepción (o devuelve una Promesa que se rechaza), por defecto, el error se trata como una excepción no capturada en process.nextTick(). Esto significa que las excepciones no capturadas en EventTarget terminarán el proceso de Node.js por defecto.

Lanzar una excepción dentro de un receptor de eventos no impedirá que se invoquen los demás manejadores registrados.

EventTarget no implementa ningún manejo predeterminado especial para eventos de tipo 'error' como EventEmitter.

Actualmente, los errores se reenvían primero al evento process.on('error') antes de llegar a process.on('uncaughtException'). Este comportamiento está obsoleto y cambiará en una versión futura para alinear EventTarget con otras API de Node.js. Cualquier código que dependa del evento process.on('error') debe alinearse con el nuevo comportamiento.

Clase: Event

[Historial]

VersiónCambios
v15.0.0La clase Event ahora está disponible a través del objeto global.
v14.5.0Agregado en: v14.5.0

El objeto Event es una adaptación de la Event Web API. Las instancias son creadas internamente por Node.js.

event.bubbles

Añadido en: v14.5.0

Esto no se utiliza en Node.js y se proporciona únicamente para completar la información.

event.cancelBubble

Añadido en: v14.5.0

[Estable: 3 - Legado]

Estable: 3 Estabilidad: 3 - Legado: Use event.stopPropagation() en su lugar.

Alias para event.stopPropagation() si se establece en true. Esto no se utiliza en Node.js y se proporciona únicamente para completar la información.

event.cancelable

Añadido en: v14.5.0

  • Tipo: <boolean> Verdadero si el evento fue creado con la opción cancelable.

event.composed

Añadido en: v14.5.0

Esto no se utiliza en Node.js y se proporciona únicamente para completar la información.

event.composedPath()

Agregado en: v14.5.0

Devuelve un array que contiene el EventTarget actual como la única entrada o vacío si el evento no está siendo despachado. Esto no se utiliza en Node.js y se proporciona únicamente para que esté completo.

event.currentTarget

Agregado en: v14.5.0

Alias para event.target.

event.defaultPrevented

Agregado en: v14.5.0

Es true si cancelable es true y se ha llamado a event.preventDefault().

event.eventPhase

Agregado en: v14.5.0

  • Tipo: <number> Devuelve 0 mientras un evento no está siendo despachado, 2 mientras está siendo despachado.

Esto no se utiliza en Node.js y se proporciona únicamente para que esté completo.

event.initEvent(type[, bubbles[, cancelable]])

Agregado en: v19.5.0

[Estable: 3 - Legado]

Estable: 3 Estabilidad: 3 - Legado: La especificación WHATWG lo considera obsoleto y los usuarios no deberían usarlo en absoluto.

Redundante con los constructores de eventos e incapaz de establecer composed. Esto no se utiliza en Node.js y se proporciona únicamente para que esté completo.

event.isTrusted

Agregado en: v14.5.0

El evento "abort" de <AbortSignal> se emite con isTrusted establecido en true. El valor es false en todos los demás casos.

event.preventDefault()

Agregado en: v14.5.0

Establece la propiedad defaultPrevented en true si cancelable es true.

event.returnValue

Agregado en: v14.5.0

[Estable: 3 - Legado]

Estable: 3 Estabilidad: 3 - Legado: Utilice event.defaultPrevented en su lugar.

  • Tipo: <boolean> True si el evento no ha sido cancelado.

El valor de event.returnValue siempre es lo opuesto de event.defaultPrevented. Esto no se utiliza en Node.js y se proporciona puramente para estar completo.

event.srcElement

Agregado en: v14.5.0

[Estable: 3 - Legado]

Estable: 3 Estabilidad: 3 - Legado: Use event.target en su lugar.

Alias para event.target.

event.stopImmediatePropagation()

Agregado en: v14.5.0

Detiene la invocación de los listeners de eventos después de que el actual se complete.

event.stopPropagation()

Agregado en: v14.5.0

Esto no se utiliza en Node.js y se proporciona puramente para completar la funcionalidad.

event.target

Agregado en: v14.5.0

event.timeStamp

Agregado en: v14.5.0

La marca de tiempo en milisegundos cuando se creó el objeto Event.

event.type

Agregado en: v14.5.0

El identificador del tipo de evento.

Clase: EventTarget

[Historial]

VersiónCambios
v15.0.0La clase EventTarget ahora está disponible a través del objeto global.
v14.5.0Añadido en: v14.5.0

eventTarget.addEventListener(type, listener[, options])

[Historial]

VersiónCambios
v15.4.0Se agregó soporte para la opción signal.
v14.5.0Añadido en: v14.5.0
  • type <string>
  • listener <Function> | <EventListener>
  • options <Object>
    • once <boolean> Cuando es true, el listener se elimina automáticamente cuando se invoca por primera vez. Predeterminado: false.
    • passive <boolean> Cuando es true, sirve como una sugerencia de que el listener no llamará al método preventDefault() del objeto Event. Predeterminado: false.
    • capture <boolean> No es utilizado directamente por Node.js. Añadido para la integridad de la API. Predeterminado: false.
    • signal <AbortSignal> El listener se eliminará cuando se llame al método abort() del objeto AbortSignal dado.

Agrega un nuevo controlador para el evento type. Cualquier listener dado se agrega solo una vez por type y por valor de opción capture.

Si la opción once es true, el listener se elimina después de la próxima vez que se envíe un evento type.

Node.js no utiliza la opción capture de ninguna manera funcional más allá de rastrear los listeners de eventos registrados según la especificación EventTarget. Específicamente, la opción capture se utiliza como parte de la clave al registrar un listener. Cualquier listener individual se puede agregar una vez con capture = false y una vez con capture = true.

js
function handler(event) {}

const target = new EventTarget()
target.addEventListener('foo', handler, { capture: true }) // first
target.addEventListener('foo', handler, { capture: false }) // second

// Removes the second instance of handler
target.removeEventListener('foo', handler)

// Removes the first instance of handler
target.removeEventListener('foo', handler, { capture: true })

eventTarget.dispatchEvent(event)

Agregado en: v14.5.0

  • event <Event>
  • Devuelve: <boolean> true si el valor del atributo cancelable del evento es falso o no se invocó su método preventDefault(), de lo contrario, false.

Envía el event a la lista de controladores para event.type.

Los detectores de eventos registrados se invocan de forma síncrona en el orden en que se registraron.

eventTarget.removeEventListener(type, listener[, options])

Agregado en: v14.5.0

Remueve el listener de la lista de controladores para el evento type.

Clase: CustomEvent

[Historial]

VersiónCambios
v23.0.0Ya no es experimental.
v22.1.0, v20.13.0CustomEvent ahora es estable.
v19.0.0Ya no está detrás del flag de CLI --experimental-global-customevent.
v18.7.0, v16.17.0Agregado en: v18.7.0, v16.17.0

[Estable: 2 - Estable]

Estable: 2 Estabilidad: 2 - Estable

El objeto CustomEvent es una adaptación de la Web API CustomEvent. Las instancias se crean internamente por Node.js.

event.detail

[Historial]

VersiónCambios
v22.1.0, v20.13.0CustomEvent ahora es estable.
v18.7.0, v16.17.0Agregado en: v18.7.0, v16.17.0

[Estable: 2 - Estable]

Estable: 2 Estabilidad: 2 - Estable

  • Tipo: <any> Devuelve datos personalizados pasados al inicializar.

De solo lectura.

Clase: NodeEventTarget

Agregado en: v14.5.0

NodeEventTarget es una extensión específica de Node.js para EventTarget que emula un subconjunto de la API de EventEmitter.

nodeEventTarget.addListener(type, listener)

Agregado en: v14.5.0

Extensión específica de Node.js para la clase EventTarget que emula la API equivalente de EventEmitter. La única diferencia entre addListener() y addEventListener() es que addListener() devolverá una referencia a EventTarget.

nodeEventTarget.emit(type, arg)

Agregado en: v15.2.0

  • type <string>
  • arg <any>
  • Devuelve: <boolean> true si existen listeners de eventos registrados para el type, de lo contrario false.

Extensión específica de Node.js para la clase EventTarget que despacha el arg a la lista de manejadores para type.

nodeEventTarget.eventNames()

Agregado en: v14.5.0

Extensión específica de Node.js a la clase EventTarget que devuelve un array de nombres type de eventos para los que se han registrado listeners de eventos.

nodeEventTarget.listenerCount(type)

Agregado en: v14.5.0

Extensión específica de Node.js a la clase EventTarget que devuelve el número de listeners de eventos registrados para el type.

nodeEventTarget.setMaxListeners(n)

Agregado en: v14.5.0

Extensión específica de Node.js a la clase EventTarget que establece el número máximo de listeners de eventos como n.

nodeEventTarget.getMaxListeners()

Agregado en: v14.5.0

Extensión específica de Node.js para la clase EventTarget que devuelve el número máximo de escuchas de eventos.

nodeEventTarget.off(type, listener[, options])

Agregado en: v14.5.0

Alias específico de Node.js para eventTarget.removeEventListener().

nodeEventTarget.on(type, listener)

Agregado en: v14.5.0

Alias específico de Node.js para eventTarget.addEventListener().

nodeEventTarget.once(type, listener)

Agregado en: v14.5.0

Extensión específica de Node.js a la clase EventTarget que añade un listener once para el type de evento dado. Esto es equivalente a llamar a on con la opción once establecida en true.

nodeEventTarget.removeAllListeners([type])

Agregado en: v14.5.0

Extensión específica de Node.js para la clase EventTarget. Si se especifica type, elimina todos los listeners registrados para type, de lo contrario, elimina todos los listeners registrados.

nodeEventTarget.removeListener(type, listener[, options])

Agregado en: v14.5.0

Extensión específica de Node.js para la clase EventTarget que elimina el listener para el type dado. La única diferencia entre removeListener() y removeEventListener() es que removeListener() devolverá una referencia al EventTarget.