W3docs

Promesas de JavaScript

Aprende las Promesas de JavaScript: estados pending, fulfilled y rejected, la función ejecutora con resolve y reject, then/catch/finally y microtareas.

Las promesas en JavaScript son una herramienta poderosa para gestionar operaciones asíncronas, lo que permite a los desarrolladores escribir código más limpio y robusto. Este capítulo explica qué es una promesa, los tres estados en los que puede encontrarse, cómo funciona la función ejecutora con resolve y reject, cómo consumir resultados con .then, .catch y .finally, y cuándo se ejecutan realmente las devoluciones de llamada de las promesas (la cola de microtareas). Comprender estos fundamentos es esencial antes de avanzar hacia el encadenamiento, la API de Promise y async/await.

Introducción a las Promesas de JavaScript

Una Promise es un object que representa un valor que puede no estar disponible todavía, pero que lo estará en algún momento en el futuro. En lugar de pasar una devolución de llamada a una función asíncrona y esperar que se ejecute, recibes un object promise de inmediato y le adjuntas devoluciones de llamada. Esto evita las devoluciones de llamada profundamente anidadas, conocidas comúnmente como "callback hell", y te proporciona una forma única y consistente de manejar tanto el éxito como el fallo.

Una tarea asíncrona típica —una solicitud de red, un temporizador, la lectura de un archivo— no tiene su resultado disponible de inmediato. La promesa es un marcador de posición para ese resultado.

Los Tres Estados de una Promesa

Una promesa se encuentra siempre en exactamente uno de tres estados:

  • pending — el estado inicial; la operación aún no ha completado.
  • fulfilled — la operación se completó con éxito y la promesa tiene un valor.
  • rejected — la operación falló y la promesa tiene una razón (generalmente un Error).

Una promesa en estado pending puede pasar a fulfilled o rejected. Una vez que lo hace, está settled y nunca podrá cambiar de estado. Esta transición unidireccional y única es lo que hace que las promesas sean predecibles: una devolución de llamada .then adjunta a una promesa ya cumplida seguirá ejecutándose, y una promesa nunca puede pasar de fulfilled a rejected.

                  ┌─────────────┐  resolve(value)   ┌─────────────┐
                  │   pending   │ ────────────────▶ │  fulfilled  │
   new Promise ─▶ │             │                   └─────────────┘
                  │             │  reject(reason)   ┌─────────────┐
                  └─────────────┘ ────────────────▶ │  rejected   │
                                                    └─────────────┘

Creación de una Promesa

Para crear una promesa, llamas al constructor Promise y le pasas una función denominada executor. El executor se ejecuta de forma inmediata y síncrona en el momento en que se crea la promesa. Recibe dos funciones como argumentos, convencionalmente denominadas resolve y reject:

  • Llama a resolve(value) para cumplir la promesa con value.
  • Llama a reject(reason) para rechazar la promesa con reason.

Hasta que llames a una de ellas, la promesa permanece en estado pending.


javascript— editable

El executor recibe resolve y reject para que pueda resolver la promesa una vez que finalice el trabajo asíncrono. Aquí la promesa se cumple después de un temporizador de un segundo:


javascript— editable

Nota: Solo la primera llamada a resolve o reject tiene efecto. Una vez que una promesa está settled, cualquier llamada posterior a resolve o reject se ignora. Además, si el executor lanza un error de forma síncrona, la promesa se rechaza automáticamente con ese error.

Gestión de Resultados con .then, .catch y .finally

Una vez creada una promesa, se consume su resultado con los métodos .then, .catch y .finally. Así es como el resto de tu código reacciona a una promesa settled.

El método then

El método .then se utiliza para programar una devolución de llamada que se ejecute cuando la promesa se cumpla. Para que una promesa se cumpla, se debe llamar al método resolve. El argumento que pasas al método resolve será el valor final de la promesa.


javascript— editable

En este código, la promesa solo se cumplirá después de que transcurran los 1000 ms del timeout y se llame al método resolve con "Done!".

La función en la parte then solo se ejecuta después de que se llame al método resolve.

.then también puede aceptar un segundo argumento —un manejador de rechazo— pero usar un .catch separado (ver más abajo) es más claro y también captura errores de manejadores anteriores.

El método .catch

El método .catch se utiliza para manejar la promesa si es rechazada. Esto significa que se lanzó un error en el bloque de la función de la promesa o se llamó al método reject.


javascript— editable

Para patrones de manejo de errores más ricos —rechazo frente a errores lanzados, relanzamiento y recuperación dentro de una cadena— consulta Manejo de errores con Promesas.

El método .finally

El método .finally te permite ejecutar código después de que la promesa esté settled, independientemente de su resultado. No recibe argumentos (no sabe si la promesa se cumplió o se rechazó) y pasa el resultado o el error sin modificaciones, por lo que es ideal para tareas de limpieza como ocultar un indicador de carga.


javascript— editable

¿Cuándo Se Ejecutan las Devoluciones de Llamada de las Promesas? (Microtareas)

Una sorpresa habitual es que las devoluciones de llamada de .then, .catch y .finally nunca se ejecutan de forma síncrona, incluso si la promesa ya está settled. Se programan en la cola de microtareas, que el motor procesa solo después de que termine el código síncrono actual.

Esto significa que el código síncrono siempre se ejecuta primero, y las devoluciones de llamada de las promesas se ejecutan antes que los temporizadores (setTimeout), que están en la cola de macrotareas separada.


javascript— editable

Aunque la promesa se resuelve de inmediato y el timeout es 0, la devolución de llamada de la promesa (3) se ejecuta antes que la del timeout (4), porque la cola de microtareas se vacía completamente antes de que se ejecute la siguiente macrotarea.

Obtención de Datos de una API usando Promesas

Este ejemplo muestra cómo obtener datos de una API remota usando promesas.


javascript— editable

Encadenamiento de Promesas

El encadenamiento de promesas es una funcionalidad poderosa que te permite vincular múltiples operaciones asíncronas. Cada .then devuelve una nueva promesa, y lo que return desde un manejador se convierte en el valor de cumplimiento de esa nueva promesa —por eso el ejemplo a continuación lleva un valor a través de varios pasos. Para más información, consulta JavaScript: Promesas y Encadenamiento.


javascript— editable

Integración de async/await con Promesas de JavaScript

Usar async/await de manera efectiva puede simplificar el manejo de operaciones asíncronas, haciendo tu código más limpio y fácil de entender mientras se mantiene toda la potencia de las promesas de JavaScript. Aprenderás más sobre esto en JavaScript async/await, pero aquí tienes un ejemplo sencillo.


javascript— editable

Conclusión

Dominar las promesas de JavaScript es fundamental para cualquier desarrollador que desee gestionar operaciones asíncronas de forma eficiente. Recuerda el modelo central: una promesa está en estado pending hasta que el executor llama a resolve o reject, tras lo cual queda settled para siempre; lees el resultado con .then/.catch/.finally; y esas devoluciones de llamada siempre se ejecutan como microtareas, después del código síncrono actual.

Dónde ir a continuación

Práctica

Práctica
¿Qué es una promesa en JavaScript?
¿Qué es una promesa en JavaScript?
Was this page helpful?