Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dariomaranes/intro-web-2025/llms.txt

Use this file to discover all available pages before exploring further.

Promises

Una Promise (promesa) es un objeto que representa el resultado eventual de una operación asíncrona. Las Promises hacen el código asíncrono más fácil de leer y mantener que los callbacks anidados.

¿Qué es una Promise?

Una Promise es un objeto que puede estar en uno de tres estados:
  • Pending (⏳ Pendiente): Estado inicial, la operación aún no ha terminado
  • Fulfilled (✅ Cumplida): La operación se completó exitosamente
  • Rejected (❌ Rechazada): La operación falló
const promise = new Promise((resolve, reject) => {
  // Operación asíncrona aquí
});

console.log(promise); // Promise { <pending> }
Una vez que una Promise está fulfilled o rejected, su estado no puede cambiar. Se dice que está “settled” (resuelta).

Crear una Promise

Para crear una Promise, usas el constructor Promise con una función que recibe dos parámetros: resolve y reject.

Promise Resuelta (Fulfilled)

const resolvePromiseBtn = document.getElementById("promise-resolved");

resolvePromiseBtn.addEventListener("click", function () {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("✅ Operación exitosa");
    }, 2000);
  });

  console.log(promise);

  promise
    .then((mensaje) => console.log(mensaje))
    .catch((error) => console.log(error));
});
Flujo de ejecución:
  1. Se crea la Promise (estado: pending)
  2. Se imprime la Promise en la consola (muestra Promise { <pending> })
  3. Después de 2 segundos, se llama a resolve()
  4. La Promise cambia a estado fulfilled
  5. Se ejecuta el callback en .then()
  6. Se imprime ”✅ Operación exitosa”

Promise Rechazada (Rejected)

const rejectPromiseBtn = document.getElementById("promise-rejected");

rejectPromiseBtn.addEventListener("click", function () {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("❌ Hubo un error");
    }, 2000);
  });

  promise
    .then((mensaje) => console.log(mensaje))
    .catch((error) => console.log(error));
});
Flujo de ejecución:
  1. Se crea la Promise
  2. Después de 2 segundos, se llama a reject()
  3. La Promise cambia a estado rejected
  4. Se salta el .then() y se ejecuta .catch()
  5. Se imprime ”❌ Hubo un error”
Si una Promise es rejected y no tienes un .catch(), obtendrás un error “Unhandled Promise Rejection” en la consola.

Consumir Promises: .then() y .catch()

Una vez que tienes una Promise, la “consumes” con .then() y .catch():
promise
  .then((resultado) => {
    // Se ejecuta si la Promise se resuelve exitosamente
    console.log('Exitoso:', resultado);
  })
  .catch((error) => {
    // Se ejecuta si la Promise es rechazada
    console.error('Error:', error);
  });

Métodos de Promise

Recibe dos funciones opcionales:
  • La primera se ejecuta si la Promise es fulfilled
  • La segunda se ejecuta si la Promise es rejected
promise.then(
  (resultado) => console.log('Exitoso:', resultado),
  (error) => console.error('Error:', error)
);
Retorna una nueva Promise, lo que permite encadenar.
Maneja errores. Es equivalente a .then(null, onRejected).
promise.catch((error) => {
  console.error('Error:', error);
});
También retorna una Promise, permitiendo encadenar más.
Se ejecuta siempre, sin importar si la Promise fue fulfilled o rejected.
promise
  .then(resultado => console.log(resultado))
  .catch(error => console.error(error))
  .finally(() => console.log('Operación completada'));
Útil para limpieza (ej: cerrar spinners de carga).

Encadenar Promises

Una de las grandes ventajas de las Promises es que puedes encadenarlas:
fetch('/api/user/1')
  .then((response) => {
    console.log('Respuesta recibida');
    return response.json(); // Retorna otra Promise
  })
  .then((data) => {
    console.log('Datos parseados:', data);
    return procesarDatos(data); // Retorna otra Promise
  })
  .then((resultado) => {
    console.log('Datos procesados:', resultado);
  })
  .catch((error) => {
    console.error('Error en cualquier paso:', error);
  });
Ventajas sobre callbacks:
  • Código más plano (no hay pirámide de callbacks)
  • Un solo .catch() maneja errores de todos los pasos
  • Más fácil de leer y mantener
Cada .then() retorna una nueva Promise. Si retornas un valor, se envuelve automáticamente en una Promise resuelta.

Ejemplo: De Callbacks a Promises

Con Callbacks (Callback Hell)

getUser(userId, (error, user) => {
  if (error) {
    console.error(error);
    return;
  }
  getOrders(user.id, (error, orders) => {
    if (error) {
      console.error(error);
      return;
    }
    processOrders(orders, (error, result) => {
      if (error) {
        console.error(error);
        return;
      }
      console.log('Resultado:', result);
    });
  });
});

Con Promises

getUser(userId)
  .then(user => getOrders(user.id))
  .then(orders => processOrders(orders))
  .then(result => console.log('Resultado:', result))
  .catch(error => console.error(error));
¡Mucho más limpio y fácil de leer!

Promise.all(): Múltiples Promises en Paralelo

Cuando necesitas esperar a que varias Promises terminen:
const promesa1 = fetch('/api/users');
const promesa2 = fetch('/api/products');
const promesa3 = fetch('/api/orders');

Promise.all([promesa1, promesa2, promesa3])
  .then(([usuarios, productos, ordenes]) => {
    console.log('Todas las peticiones completadas');
    console.log('Usuarios:', usuarios);
    console.log('Productos:', productos);
    console.log('Ordenes:', ordenes);
  })
  .catch(error => {
    console.error('Al menos una petición falló:', error);
  });
Características:
  • Espera a que todas las Promises se resuelvan
  • Si cualquiera falla, Promise.all() es rejected inmediatamente
  • Retorna un array con todos los resultados en el mismo orden

Otros Métodos de Promise

Retorna la Promise que termine primero (fulfilled o rejected).
const promesa1 = new Promise(resolve => setTimeout(() => resolve('Lento'), 2000));
const promesa2 = new Promise(resolve => setTimeout(() => resolve('Rápido'), 1000));

Promise.race([promesa1, promesa2])
  .then(resultado => console.log(resultado)); // "Rápido"
Útil para timeouts o racing conditions.

Manejo de Errores

Un .catch() para Todos

fetch('/api/data')
  .then(response => response.json())
  .then(data => procesarDatos(data))
  .then(resultado => mostrarResultado(resultado))
  .catch(error => {
    // Maneja errores de CUALQUIERA de los pasos anteriores
    console.error('Error en alguna parte:', error);
  });

.catch() en el Medio

fetch('/api/data')
  .then(response => response.json())
  .catch(error => {
    console.error('Error al obtener datos:', error);
    return { default: true }; // Valor por defecto
  })
  .then(data => {
    // Se ejecuta incluso si hubo error arriba
    console.log('Datos:', data);
  });
Si un .catch() no lanza un error, la cadena continúa normalmente. Esto permite recuperarse de errores.

Crear Promises de Valores

// Promise resuelta inmediatamente
const promesaResuelta = Promise.resolve('Valor');

// Promise rechazada inmediatamente
const promesaRechazada = Promise.reject(new Error('Error'));

// Útil para convertir valores en Promises
function obtenerDatos(cache) {
  if (cache) {
    return Promise.resolve(cache); // Retorna Promise
  }
  return fetch('/api/data'); // También retorna Promise
}

Buenas Prácticas

1

Siempre maneja errores

// ❌ Mal: Sin .catch()
fetch('/api/data').then(handleData);

// ✅ Bien: Con .catch()
fetch('/api/data')
  .then(handleData)
  .catch(handleError);
2

Retorna Promises en cadenas

// ❌ Mal: No retorna
promise.then(() => {
  otraPromise(); // Esta Promise se ignora
});

// ✅ Bien: Retorna la Promise
promise.then(() => {
  return otraPromise(); // Se encadena correctamente
});
3

Evita mezclar callbacks y Promises

// ❌ Confuso: Mezcla callbacks con Promises
fetch('/api/data').then(data => {
  setTimeout(() => {
    procesarDatos(data, (resultado) => {
      // ...
    });
  }, 1000);
});

// ✅ Mejor: Todo con Promises
fetch('/api/data')
  .then(data => esperarUnSegundo())
  .then(() => procesarDatosPromise(data));

Próximos Pasos

Async/Await

Aprende la sintaxis más moderna para trabajar con Promises

Fetch API

Usa Promises para hacer peticiones HTTP

Build docs developers (and LLMs) love