¿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

 PromisesObservables (RxJS)
ValoresUno soloMúltiples, continuos
CancelaciónNoSí (unsubscribe)
ComposiciónLimitadaTotal (switchMap, merge, combineLatest…)
Caso bancarioPetición únicaCotizaciones 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ónCuándo usarlaEjemplo bancario
BehaviorSubjectEstado simple y global, sin boilerplateauth.currentUser$, sesión activa
NgRx StoreEstado complejo, múltiples features, trazabilidadSaldos, transacciones, flujo de préstamos
Angular SignalsEstado 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 → catchErrorrefreshToken()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:

  1. Una referencia de @Input() cambia
  2. Ocurre un evento DOM interno
  3. El async pipe emite un nuevo valor
  4. 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 suscriptores
  • distinctUntilKeyChanged — 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, concatMap y exhaustMap
  • 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

  • ✔️ switchMap vs exhaustMap — 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


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.

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.