JavaScript de Cero a Experto / Patrones y observables
Máquina de estados: transiciones con permiso
"El botón de pagar se habilitó dos veces", "la petición mostró éxito Y error a la vez", "¿cómo llegó la app a ESTE estado?" — la familia de bugs más desesperante nace de estados implícitos regados en booleanos. La máquina de estados los extermina con una idea de kínder: declarar QUÉ estados existen y QUÉ caminos entre ellos están permitidos. Todo lo demás, prohibido por diseño.
La lavadora
El olor del bug: booleanos en pandilla
// tres booleanos = 8 combinaciones posibles...
let cargando = false;
let exito = false;
let error = false;
// ...y solo 4 tienen sentido. Las otras 4 son bugs esperando:
// ¿cargando=true Y error=true? ¿exito=true Y error=true?
// cada función debe acordarse de apagar los otros dos. Alguna olvidará.¿Reconoces el trío? Son los estados de carga del módulo 10 — allá los
manejaste con disciplina dentro de un try/catch. La máquina convierte
esa disciplina en estructura: UN string de estado y una tabla de caminos.
La máquina en 20 líneas
Lee la tabla como un mapa de la lavadora: cada estado lista SOLO las acciones que acepta y a dónde llevan. "Éxito y error a la vez" ya no es un bug que manejar — es un estado que NO EXISTE: hay un solo string, y solo cambia por caminos declarados. Y el bonus de leerlo: la tabla ES la documentación del flujo — un diseñador la entiende sin saber programar.
Máquina + store: el combo que pinta interfaces
La máquina decide; el store (lección pasada) AVISA. Juntas son el patrón de interfaces robustas: el estado de la máquina vive en un store, la UI se suscribe y pinta según el string:
const estadoUI = crearEstado(consulta.estado);
function enviar(accion) {
estadoUI.set(consulta.enviar(accion)); // mover Y avisar, juntos
}
estadoUI.suscribir((estado) => {
// la UI es un mapa estado → pantalla (ni un if de booleanos)
if (estado === "cargando") console.log("UI: spinner");
if (estado === "lista") console.log("UI: mostrar datos");
if (estado === "conError") console.log("UI: mensaje + botón reintentar");
});Nota honesta de alcance: para flujos de 2 estados, la máquina es
burocracia — un booleano honesto basta. Empieza a pagar desde 3-4 estados
con reglas de paso (formularios multi-etapa, pedidos, juegos, la
autenticación). Y en el mundo real existe XState, la librería que
industrializa este patrón (visualizador de diagramas incluido) — cuando la
veas, su createMachine te parecerá un déjà vu de tus 20 líneas.
En tu e-commerce, un usuario logró pagar dos veces el mismo pedido haciendo doble clic rapidísimo. Con máquina de estados, ¿por qué es imposible?
Mini-reto
Modela el ciclo de un gasto compartido de "Mi Bolsillo": estados
borrador → pendiente → aprobado | rechazado, con reglas: desde borrador
solo se puede enviar; desde pendiente, aprobar o rechazar; desde
rechazado se puede corregir (vuelve a borrador); aprobado es terminal
(ningún camino sale). Pruébala: el camino feliz completo, un rechazo con
corrección, y DOS intentos prohibidos atrapados con try/catch. Remate:
imprime puede("aprobar") en cada estado — esa función es la que
habilitaría botones en la UI.
Qué sigue
Módulo casi cerrado: módulos, singleton, factory, observer, store y máquina — el kit de arquitectura completo. El reto los pone a trabajar JUNTOS: "Mi Bolsillo reactivo", una mini-arquitectura donde la factory fabrica, el bus comunica y las suscripciones mantienen todo sincronizado. Sin DOM, sin framework: puro diseño tuyo.