Como hacer polling en Angular con Signals y rxResource. Buenas practicas
Tiempo estimado de lectura: 4 min
Ideas clave
- rxResource convierte Observables en señales gestionadas con limpieza automática.
- Prefiere polling reactivo dentro del
loaderderxResource(timer +switchMap). - Implementa retry/backoff, pausa con Page Visibility API y evita polling agresivo en móviles.
- Usa
switchMappara cancelar peticiones lentas yshareReplaypara cache compartida.
Como hacer polling en Angular con Signals y rxResource. Si esa es la pregunta que te trajo hasta aquí, perfecto: vamos directo al punto. Polling no es magia; es un patrón con trampas si no lo diseñas pensando en resiliencia, eficiencia y vida útil de la UI. Aquí tienes cómo hacerlo bien, con ejemplos prácticos y criterios que realmente importan.
Polling no es solo hacer peticiones cada X segundos: es hacerlo con criterio.
Resumen rápido (lectores con prisa)
Qué es: rxResource convierte Observables en señales gestionadas (valor, carga, error, reload).
Cuándo usar: dashboards y estados donde 2–30s de retraso son aceptables; no para latencia < 1s.
Por qué importa: limpieza automática, cancelación de peticiones y patrón más seguro que intervalos manuales.
Cómo: preferible encapsular polling dentro del loader con timer + switchMap, añadir retry/backoff y pausar con Page Visibility API.
¿Qué es rxResource y por qué importa para el polling?
rxResource (paquete: @angular/core/rxjs-interop) convierte un Observable en una señal gestionada: expone .value(), .isLoading(), .error() y .reload(). Maneja la limpieza de suscripciones automáticamente cuando el componente se destruye, lo que reduce significativamente el boilerplate y las fugas de memoria. Documentación.
Eso cambia las reglas del juego: el loader de un resource puede devolver un Observable que emita múltiples valores (ideal para polling). En lugar de gestionar intervalos manuales y ngOnDestroy, encapsulas la lógica reactiva en el resource.
Estrategias válidas: cuándo usar cada una
Hay dos patrones útiles: el imperativo (reload) y el declarativo (loader periódico). Usa el primero cuando el usuario debe controlar el ciclo (pausar/reanudar). Prefiere el segundo como opción por defecto: es más limpia y segura.
1) Polling imperativo con reload()
Útil si la UI ofrece control explícito (botón pausa).
// patrón simplificado
const dataResource = rxResource({ loader: () => http.get('/api/status') });
const id = window.setInterval(() => dataResource.reload(), 5000);
// clearInterval(id) al destruir/comportamiento de pausa
Ventaja: control directo. Desventaja: gestión manual del ciclo de vida y riesgo de olvidarte de limpiar el intervalo.
2) Polling reactivo dentro del loader (recomendado)
Encapsula todo en el loader. El resource escucha un Observable que emite periódicamente.
import { timer, EMPTY, merge, of, fromEvent } from 'rxjs';
import { switchMap, map, retry, catchError } from 'rxjs/operators';
dataResource = rxResource({
request: () => ({ interval: pollIntervalSignal() }),
loader: ({ request }) => {
const visibility$ = merge(
of(document.visibilityState === 'visible'),
fromEvent(document, 'visibilitychange').pipe(map(() => document.visibilityState === 'visible'))
);
return visibility$.pipe(
switchMap(visible =>
visible
? timer(0, request.interval).pipe(
switchMap(() => http.get('/api/metrics')),
retry({ count: 3, delay: 1000 }),
catchError(() => EMPTY) // mantiene vivo el stream ante errores transitorios
)
: EMPTY
)
);
}
});
Beneficios prácticos: limpieza automática, cancelación de peticiones lentas gracias a switchMap, y pause automático con Page Visibility API.
Referencia útil sobre retry. Página sobre Page Visibility API (MDN).
Buenas prácticas obligatorias (no opcionales)
- Usa
switchMappara evitar race conditions. Si una petición tarda más que el intervalo, cancelas la anterior. - Implementa backoff para errores persistentes. No bombardees un servidor con 500s:
retryWhen+ delay exponencial. - Pausa el polling cuando la pestaña está oculta (Page Visibility API) o cuando el dispositivo entra en modo bajo consumo.
- Evita polling agresivo en dispositivos móviles. Considera un throttle dinámico o reducir frecuencia en redes móviles.
- Agrupa requests cuando sea posible (batching/
forkJoin) para reducir overhead. - Usa cache + TTL (
shareReplay(1)con invalidación) si la misma petición la hacen múltiples componentes. - Supervisión: expón métricas de errores/latencia en logs para detectar piezas rotas del polling.
Testing y observabilidad
- Testea con
fakeAsyncytick()para simular intervalos en unit tests. - Mockea
rxResourceutilizando proveedores enTestBedpara controlar emisiones. - Registra fallos y frecuencia de reintentos; si ves un patrón de reintentos masivos, cambia a backoff más agresivo o al modo “degraded”.
Cuándo no usar polling
No uses polling si necesitas latencia < 1s o alta frecuencia. Para actualizaciones en tiempo real, usa WebSockets o SSE. Polling sigue siendo válido para dashboards, contadores y estados donde 2–30s de retraso son aceptables.
Guías de alternativas: WebSockets / SSE.
Resumen práctico (lista rápida)
- Preferible: implementar polling dentro del
loaderderxResourcecontimer+switchMap. - Añadir: retry/backoff, Page Visibility API para pausar,
shareReplaysi es necesario. - Imperativo (
reload) sólo si la UX necesita control manual. - Evitar: polling sin control de errores o sin pausa para pestañas ocultas.
Fuentes
FAQ
¿Qué es exactamente rxResource?
rxResource convierte un Observable en una señal gestionada que expone métodos como .value(), .isLoading(), .error() y .reload(), y gestiona la limpieza de suscripciones al destruirse el componente.
¿Por qué preferir el polling dentro del loader?
Porque encapsula la lógica reactiva, permite limpieza automática, usa operadores como switchMap para cancelar peticiones y facilita pausar con APIs como Page Visibility.
¿Cuándo usar reload() en lugar de polling declarativo?
Usa reload() cuando la UX requiere control manual del ciclo (por ejemplo, un botón de pausa/reanudar). Para la mayoría de casos, el loader periódico es más seguro.
¿Cómo manejo errores transitorios sin romper el stream?
Usa operadores como retry o retryWhen con backoff y catchError retornando EMPTY para mantener vivo el stream ante errores transitorios.
¿Cómo pauso el polling cuando la pestaña está oculta?
Observa document.visibilityState o escucha el evento visibilitychange y condiciona el stream para emitir solo cuando la pestaña esté visible.
¿Es el polling adecuado en móviles?
Con precaución: evita frecuencias agresivas, reduce la tasa en redes móviles y considera estrategias de throttling dinámico o degradado.
¿Qué alternativas usar si necesito latencia menor a 1s?
Emplea WebSockets o Server-Sent Events para actualizaciones en tiempo real; el polling no es adecuado para exigencias de latencia muy baja.

Leave a Reply