FINTECH · BANCA · ANGULAR SENIOR ANGULAR EN ENTORNOS CRÍTICOS RxJS · Gestión de Estado · Seguridad · Rendimiento
¿Alguna vez has terminado una entrevista técnica para un puesto Senior en banca sintiendo que sabías las respuestas, pero no de la forma en que te las preguntaban?
No es casualidad. En fintech, el código no solo tiene que funcionar — tiene que sobrevivir a 200 peticiones por segundo, a tokens que expiran en medio de una transferencia, y a un usuario que pulsa el botón de «Pagar» tres veces porque su WiFi va lento.
En este artículo (con demo interactiva incluida) repasamos los seis pilares que diferencian a un desarrollador Angular que «sabe hacer una web» de uno que un banco contrataría sin dudar.
Lo que vas a aprender
- Por qué RxJS no es opcional en fintech — y qué pasa si usas Promises
- Los 4 operadores de RxJS que siempre aparecen en entrevistas (con casos de uso reales)
- Cuándo usar NgRx, Signals o un simple BehaviorSubject
- Cómo implementar un interceptor JWT con refresh automático — sin que el usuario note nada
- OnPush Change Detection: la diferencia entre 7 checks y 1
- Cómo prevenir memory leaks con
takeUntilDestroyed - WebSockets reactivos para datos en tiempo real
Al final encontrarás un simulador interactivo donde puedes probar cada uno de estos conceptos en vivo, directamente en el navegador.
1. ¿Por qué RxJS en Banca?
Imagina una pantalla de banca online. El saldo cambia en tiempo real. Las cotizaciones de fondos llegan por WebSocket cada segundo. Hay un buscador de IBAN que responde mientras escribes. Y hay un botón de «Transferir» que no puede ejecutarse dos veces.
Todo esto son flujos de datos asíncronos, no eventos puntuales. Y para flujos, RxJS es el lenguaje correcto.
Promises vs Observables — la tabla que deberías memorizar
| Promises | Observables (RxJS) | |
|---|---|---|
| Valores | Uno solo | Múltiples, continuos |
| Cancelación | No | Sí (unsubscribe) |
| Composición | Limitada | Total (switchMap, merge, combineLatest…) |
| Caso bancario | Petición única | Cotizaciones live, búsquedas, WebSockets |
El dato que cambia entrevistas: decir «uso RxJS porque Angular lo usa» es respuesta junior. Decir «uso RxJS porque necesito cancelar peticiones obsoletas en búsquedas y prevenir duplicados en pagos» es respuesta Senior.
2. Los 4 operadores que siempre preguntan
[IMAGEN 3 AQUÍ]
Esta es, sin exagerar, la pregunta más repetida en entrevistas Angular para banca. Y la trampa no está en la definición — está en el caso de uso.
switchMap — «Solo me importa el último valor»
typescript
searchControl.valueChanges.pipe(
debounceTime(300),
distinctUntilChanged(),
filter(q => q.length >= 3),
switchMap(query =>
cuentaService.buscar(query).pipe(
catchError(() => of([]))
)
),
takeUntilDestroyed()
).subscribe(res => this.resultados = res);
Caso bancario: buscador de IBAN. Si el usuario escribe «García», no te importan los resultados de «G», «Ga», «Gar» — solo el final. switchMap cancela automáticamente las búsquedas obsoletas.
mergeMap — «Todo es independiente, ejecútalo en paralelo»
Caso bancario: cargar simultáneamente el perfil del usuario, sus cuentas y sus tarjetas. Nada depende de nada — paralelizar es gratis.
concatMap — «El orden es la ley»
Caso bancario: procesar transacciones donde el débito tiene que completarse antes que el crédito. concatMap garantiza una cola estrictamente ordenada.
exhaustMap — «Ignora todo hasta que termine»
typescript
pagarBtn$.pipe(
exhaustMap(() =>
pagoService.ejecutar(payload).pipe(
tap(() => this.showSuccess()),
catchError(err => { this.showError(err); return EMPTY; })
)
)
).subscribe();
// 10 clics → 1 sola petición procesada ✓
Caso bancario: el botón «Pagar». Si el usuario pulsa 5 veces, solo se procesa la primera petición. Las demás se ignoran. Sin esto, podrías duplicar una transferencia.
La regla mnemotécnica
switch = búsqueda · merge = paralelo · concat = cola · exhaust = botón único
3. Gestión de Estado: NgRx, Signals o BehaviorSubject — ¿quién gana?
La pregunta no es «¿cuál es mejor?» — es «¿cuál es mejor para qué?».
| Solución | Cuándo usarla | Ejemplo bancario |
|---|---|---|
| BehaviorSubject | Estado simple y global, sin boilerplate | auth.currentUser$, sesión activa |
| NgRx Store | Estado complejo, múltiples features, trazabilidad | Saldos, transacciones, flujo de préstamos |
| Angular Signals | Estado local de componente (v16+) | Filtros de tabla, paginación, toggles UI |
Decir «uso NgRx para todo» en una entrevista es una señal de alerta. La respuesta correcta demuestra que sabes evitar boilerplate innecesario.
4. JWT Interceptor con Refresh Automático — el patrón que salva sesiones
En banca, los tokens JWT expiran cada 15-30 minutos. Una implementación mala hace logout() en el primer 401 — y el usuario pierde su transferencia a medio hacer.
La implementación correcta:
typescript
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authReq = req.clone({
setHeaders: { Authorization: `Bearer ${this.auth.getToken()}` }
});
return next.handle(authReq).pipe(
catchError(error => {
if (error.status === 401 && !req.url.includes('/auth/refresh')) {
return this.auth.refreshToken().pipe(
switchMap(newToken => {
const retryReq = req.clone({
setHeaders: { Authorization: `Bearer ${newToken}` }
});
return next.handle(retryReq);
}),
catchError(() => { this.auth.logout(); return throwError(() => error); })
);
}
return throwError(() => error);
})
);
}
Flujo: Request → 401 → catchError → refreshToken() → switchMap → reintento transparente. El usuario nunca se entera.
5. OnPush + Memory Leaks: el dúo que separa Junior de Senior
Change Detection: 7 checks vs 1 check
Por defecto, Angular revisa todo el árbol de componentes ante cualquier evento. En un dashboard con 80 componentes recibiendo datos por WebSocket cada segundo, esto es insostenible.
Con ChangeDetectionStrategy.OnPush + async pipe, Angular solo revisa el componente cuando:
- Una referencia de
@Input()cambia - Ocurre un evento DOM interno
- El
async pipeemite un nuevo valor - Se llama
markForCheck()manualmente
typescript
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template: `{{ saldo$ | async | currency:'EUR' }}`
})
export class SaldoComponent {
saldo$ = this.cuentaService.getSaldo().pipe(shareReplay(1));
}
Memory leaks: el patrón moderno
typescript
private destroyRef = inject(DestroyRef);
ngOnInit() {
this.cotizacion$.pipe(
takeUntilDestroyed(this.destroyRef)
).subscribe(precio => this.precio = precio);
}
Pregunta de entrevista: «Dame tres formas de evitar memory leaks con RxJS» →
async pipe(automático),takeUntilDestroyed(v16+),takeUntil+Subject(legacy).
6. WebSockets reactivos — datos en tiempo real sin sustos
typescript
@Injectable({ providedIn: 'root' })
export class CotizacionService {
private socket$ = webSocket<Cotizacion>('wss://api.banco.com/cotizaciones');
getCotizacion(ticker: string): Observable<Cotizacion> {
return this.socket$.pipe(
filter(msg => msg.ticker === ticker),
distinctUntilKeyChanged('precio'),
shareReplay(1),
retryWhen(errors => errors.pipe(delay(3000), take(5)))
);
}
}
Tres claves de producción:
shareReplay(1)— una sola conexión WebSocket para todos los suscriptoresdistinctUntilKeyChanged— evita re-renders si el valor no cambióretryWhen+delay— reconexión automática si la conexión se cae
Pruébalo tú mismo — Simulador Interactivo
Este simulador incluye 4 módulos en vivo: simulador-angular-fintech
Simulador Fintech.
- RxJS Operators — marble diagrams animados de
switchMap,mergeMap,concatMapyexhaustMap - Dashboard Bancario — cotizaciones en tiempo real, buscador reactivo con
switchMap, transacciones ordenadas - JWT Interceptor — simula el ciclo completo de refresh de token, con log en vivo
- Change Detection — compara visualmente Default CD (7 checks) vs OnPush (1 check)
VIDEO :
Video
Resumen: lo que un Senior de Angular en Banca debe dominar
- ✔️
switchMapvsexhaustMap— y cuándo usar cada uno - ✔️ JWT Interceptors con refresh automático
- ✔️ NgRx + Signals según el contexto, no «NgRx para todo»
- ✔️ OnPush + async pipe como estándar de rendimiento
- ✔️ Prevención de memory leaks con
takeUntilDestroyed - ✔️ WebSockets reactivos con reconexión automática
Recursos para seguir practicando
- rxjs.dev — documentación oficial
- rxjs.live — playground interactivo de marble diagrams
- ngrx.io — documentación NgRx
- blog.angular.io — roadmap oficial de Angular y Signals
EL CÓDIGO PUEDE COPIARSE.
PERO EL PENSAMIENTO ARQUITECTÓNICO ES LO QUE CONSTRUYE EL FUTURO.
Por Elizabeth Sáenz — Master en Desarrollo Fullstack & Arquitectura Cloud, Tajamar.