fromEvent() - convierte el evento en Observable
fromEvent()` es una Creation Function que convierte fuentes de eventos como eventos DOM y Node.js EventEmitter en flujos Observable.
Visión general.
fromEvent()` permite que el procesamiento asíncrono basado en eventos sea manejado en el pipeline de RxJS. Registra automáticamente los escuchadores de eventos cuando se suscriben y elimina automáticamente los escuchadores cuando se desuscriben, reduciendo así significativamente el riesgo de fugas de memoria.
Firma:.
function fromEvent<T>(
target: any,
eventName: string,
options?: EventListenerOptions | ((...args: any[]) => T)
): Observable<T>Documentación oficial: 📘 Fórmula RxJS: fromEvent()
Uso básico.
Este es el ejemplo más simple de tratar eventos DOM como Observable.
import { fromEvent } from 'rxjs';
const clicks$ = fromEvent(document, 'click');
clicks$.subscribe(event => {
console.log('Botón pulsado.:', event);
});
// Se emite un evento cada vez que se hace clic.Características importantes.
1. alta y baja automática de oyentes
La función fromEvent() registra escuchadores de eventos cuando se suscriben y los elimina automáticamente cuando se dan de baja.
import { fromEvent } from 'rxjs';
const clicks$ = fromEvent<MouseEvent>(document, 'click');
const subscription = clicks$.subscribe(event => {
console.log('Posición del clic:', event.clientX, event.clientY);
});
// 5Desuscrito después de unos segundos (el listener del evento también se borra automáticamente)
setTimeout(() => {
subscription.unsubscribe();
console.log('Desuscrito');
}, 5000);function fromEvent<T>(
target: any,
eventName: string,
options?: EventListenerOptions | ((...args: any[]) => T)
): Observable<T>Prevención de fugas de memoria
Cuando se llama a
unsubscribe(), se ejecuta automáticamente unremoveEventListener()interno. Esto elimina la necesidad de eliminar manualmente los oyentes y reduce significativamente el riesgo de fugas de memoria.
2. Cold Observable (cada suscripción registra un oyente independiente).
El Observable creado por fromEvent() es un **Cold Observable. Cada suscripción registra un receptor de eventos independiente.
import { fromEvent } from 'rxjs';
const clicks$ = fromEvent(document, 'click');
// Suscrito a1 - ListenerASuscrito a
clicks$.subscribe(() => console.log('Observer 1: Haga clic en'));
// 1Suscribirse en segundos2Añadir - ListenerBRegistrar independientemente de
setTimeout(() => {
clicks$.subscribe(() => console.log('Observer 2: Haga clic en'));
}, 1000);
// 1Ambos receptores se activan con un solo clic
// Esto es una prueba de que cada suscripción tiene oyentes independientesimport { fromEvent } from 'rxjs';
const clicks$ = fromEvent(document, 'click');
clicks$.subscribe(event => {
console.log('Botón pulsado.:', event);
});
// Se emite un evento cada vez que se hace clic.**Prueba de frío Observable
Se registra un nuevo oyente de eventos cada vez que se realiza una suscripción y se elimina cuando se cancela la suscripción. Esta es una característica de Cold Observable. Sin embargo, también tiene la propiedad Hot de que "no se pueden recibir eventos antes de la suscripción" porque la fuente de eventos (por ejemplo, elementos DOM) es externa y compartida.
3. Soporte de tipos TypeScript
Los tipos de eventos pueden especificarse explícitamente.
import { fromEvent } from 'rxjs';
const input = document.createElement('input');
input.type = 'text';
document.body.appendChild(input);
const input$ = fromEvent<InputEvent>(input, 'input');
input$.subscribe(event => {
// eventEl tipo deInputEvent
const target = event.target as HTMLInputElement;
console.log('Valor de entrada:', target.value);
});4. Cold Observable.
El fromEvent() es un **Cold Observable. Cada suscripción inicia una ejecución independiente.
import { fromEvent } from 'rxjs';
const button = document.createElement('button');
button.innerText = "Suscrito a";
document.body.appendChild(button);
const clicks$ = fromEvent(document, 'click');
// 1La segunda suscripción - Se añaden escuchadores de eventos
clicks$.subscribe(() => console.log('SuscripciónA'));
// 2La segunda suscripción - Se añade otro receptor de eventos
clicks$.subscribe(() => console.log('SuscripciónB'));
// 1Un clic activa ambos escuchadores
// Salida:
// SuscripciónA
// SuscripciónBimport { fromEvent } from 'rxjs';
const clicks$ = fromEvent(document, 'click');
clicks$.subscribe(event => {
console.log('Botón pulsado.:', event);
});
// Se emite un evento cada vez que se hace clic.Características de Cold Observable.
- Cada suscripción inicia una ejecución independiente
- Cada suscriptor recibe su propio flujo de datos
Para más información, consulte Cold Observable y Hot Observable.
Casos prácticos de uso.
1. manejo de eventos click
Controla los clics de los botones y evita los clics consecutivos.
import { fromEvent } from 'rxjs';
import { debounceTime, map } from 'rxjs';
const button = document.createElement('button');
button.innerText = "submit";
document.body.appendChild(button);
const clicks$ = fromEvent(button, 'click');
clicks$.pipe(
debounceTime(300), // 300msIgnora clics consecutivos dentro de
map(() => 'durante la transmisión...')
).subscribe(message => {
console.log(message);
// APILlamadas y otros procesos
});2. validación en tiempo real de las entradas de los formularios
Flujo de eventos de entrada y realizar la validación en tiempo real.
import { fromEvent } from 'rxjs';
import { map, debounceTime, distinctUntilChanged } from 'rxjs';
const label = document.createElement('label');
label.innerText = 'email: ';
const emailInput = document.createElement('input');
label.appendChild(emailInput);
document.body.appendChild(label);
const email$ = fromEvent<InputEvent>(emailInput, 'input');
email$.pipe(
map(event => (event.target as HTMLInputElement).value),
debounceTime(500), // después de que se haya detenido la entrada.500msProcesado más tarde
distinctUntilChanged() // Sólo cuando cambia el valor
).subscribe(email => {
console.log('Sujeto a validación:', email);
// Proceso de validación de direcciones de correo electrónico
validateEmail(email);
});
function validateEmail(email: string): void {
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
console.log(isValid ? 'Dirección de correo electrónico válida' : 'Dirección de correo electrónico no válida');
}3. Implementación de arrastrar y soltar
Combina eventos de ratón para implementar arrastrar y soltar.
import { fromEvent } from 'rxjs';
import { switchMap, takeUntil, map } from 'rxjs';
// Crear elementos arrastrables
const element = document.createElement('div');
element.style.width = '100px';
element.style.height = '100px';
element.style.backgroundColor = '#333';
element.style.position = 'absolute'; // Posicionamiento absoluto
element.style.left = '50px'; // Posición inicial
element.style.top = '50px';
element.style.cursor = 'move'; // Cursor arrastrable
document.body.appendChild(element);
const mousedown$ = fromEvent<MouseEvent>(element, 'mousedown');
const mousemove$ = fromEvent<MouseEvent>(document, 'mousemove');
const mouseup$ = fromEvent<MouseEvent>(document, 'mouseup');
mousedown$.pipe(
switchMap(startEvent => {
// Registra la posición del clic en el elemento
const startX = startEvent.clientX - element.offsetLeft;
const startY = startEvent.clientY - element.offsetTop;
return mousemove$.pipe(
map(moveEvent => ({
left: moveEvent.clientX - startX,
top: moveEvent.clientY - startY
})),
takeUntil(mouseup$) // Finaliza con ratón arriba
);
})
).subscribe(({ left, top }) => {
// Actualizar posición del elemento
element.style.left = `${left}px`;
element.style.top = `${top}px`;
});4. monitorizar eventos de desplazamiento
Utilizado para rastrear el desplazamiento infinito y la posición de desplazamiento.
function fromEvent<T>(
target: any,
eventName: string,
options?: EventListenerOptions | ((...args: any[]) => T)
): Observable<T>Usar en pipeline.
fromEvent()` es ideal para el procesamiento de tuberías a partir de un flujo de eventos.
Errores comunes.
1. Olvidar darse de baja
❌ Error - olvidarse de darse de baja provoca fugas de memoria.
function fromEvent<T>(
target: any,
eventName: string,
options?: EventListenerOptions | ((...args: any[]) => T)
): Observable<T>✅ Correcto - darse de baja siempre
WARNING
Atención fugas de memoria
En SPA y frameworks basados en componentes, siempre desuscríbete cuando destruyas un componente. Si olvidas desuscribirte, los escuchadores de eventos permanecerán y causarán fugas de memoria.
2. Registro duplicado de múltiples escuchadores de eventos
❌ Error - suscribirse al mismo evento varias veces registrará múltiples escuchadores.
CÓDIGO 14
✅ Correcto - multidifusión con share() si es necesario.
function fromEvent<T>(
target: any,
eventName: string,
options?: EventListenerOptions | ((...args: any[]) => T)
): Observable<T>Consideraciones de rendimiento.
Las consideraciones de rendimiento deben tenerse en cuenta cuando se trata de eventos de disparo de alta frecuencia (scroll, mousemove, cambiar el tamaño, etc.).
consideraciones de rendimiento
Optimización de eventos de alta frecuencia:.
throttleTime()- sólo se maneja una vez cada cierto tiempo.debounceTime()- Procesar después de que la entrada se haya detenido.distinctUntilChanged()- Procesar sólo cuando cambia el valor.
❌ Problemas de rendimiento - procesar cada cambio de tamaño.
function fromEvent<T>(
target: any,
eventName: string,
options?: EventListenerOptions | ((...args: any[]) => T)
): Observable<T>✅ Optimización - sólo se procesa una vez cada 200ms
Funciones de Creation Function relevantes.
Resumen
- fromEvent()` convierte eventos DOM y EventEmitter a Observable
- Listener registrado cuando se suscribe, borrado automáticamente cuando se desuscribe (previene fugas de memoria)
- Funciona como un Observable en caliente
- Realiza siempre la desuscripción para evitar fugas de memoria
- Optimiza los eventos de alta frecuencia con
throttleTime()ydebounceTime().
Próximos pasos.
- interval() - emitir valores a intervalos regulares](/es/guide/creation-functions/basic/interval)
- timer() - empezar a publicar después de un retraso](/es/guide/creation-functions/basic/timer)
- volver al resumen de las funciones básicas de creación](/es/guide/creation-functions/basic/)