Métodos estáticos de promesas en JavaScript (Promise.all, race, allSettled, any)

Dominar la asincronía es el paso definitivo para dejar de ser un principiante en JavaScript. En este artículo, exploraremos cómo Promise.all, race, allSettled y any te permiten gestionar múltiples tareas en paralelo como un experto. Aprende a elegir el método exacto para optimizar la velocidad de tus aplicaciones y evitar errores críticos.

Métodos estáticos de promesas en JavaScript (Promise.all, race, allSettled, any)

1. ¿Qué son los métodos estáticos de promesas en javascript?

Los métodos estáticos de las promesas son funciones que pertenecen directamente a la clase Promise, en lugar de a una instancia específica (un objeto creado con new Promise()). Se utilizan principalmente para gestionar varias operaciones asíncronas al mismo tiempo o para crear promesas de forma inmediata.

👉 Es decir:

  • Estáticos → se usan así: Promise.algo()
  • De instancia → se usan así: miPromesa.then()

IDEA CLAVE:
Estos métodos estáticos sirven para trabajar con múltiples promesas al mismo tiempo y controlar cómo se resuelven en conjunto.

1.1. Ejemplo base para entender el concepto

// ❌ Esto es una instancia de Promise
const promesa = new Promise((resolve, reject) => {
  resolve("OK");
});

// 👉 Método de instancia (se usa sobre la promesa)
promesa.then(resultado => {
  console.log(resultado);
});


// ✅ Esto es un método estático (NO depende de una instancia)
Promise.resolve("Hola mundo")
  .then(resultado => {
    console.log(resultado);
  });Lenguaje del código: JavaScript (javascript)

EXPLICACIÓN:

  • new Promise(…) → crea una instancia de promesa
  • promesa.then(…) → método de instancia (se ejecuta sobre ESA promesa)
  • Promise.resolve(…) → método estático (No necesitamos crear una promesa antes, lo usamos directamente desde Promise)

1.2. Métodos estáticos principales (los que vas a dominar)

JavaScript tiene varios, pero los más importantes son:

  • Promise.all()
  • Promise.race()
  • Promise.allSettled()
  • Promise.any()

2. Promise.all()

Promise.all() es un método estático que se utiliza cuando tienes varias operaciones asíncronas ejecutándose al mismo tiempo y necesitas esperar a que todas terminen correctamente para continuar con tu código.

Es como un «punto de control»: si todas las promesas se cumplen, avanzas con todos los datos juntos; si una sola falla, el proceso se detiene y se lanza un error.

2.1. Sintaxis básica

La sintaxis es sencilla, recibe un iterable (generalmente un array) de promesas:

Promise.all([promesa1, promesa2, promesa3])
  .then((resultados) => {
    // Se ejecuta si TODAS las promesas se resuelven
    // 'resultados' es un array con los valores de cada promesa
  })
  .catch((error) => {
    // Se ejecuta si AL MENOS UNA promesa es rechazada
    // 'error' contiene el motivo del primer fallo detectado
  });Lenguaje del código: JavaScript (javascript)

2.2. Principales características de promise.all

Las características de Promise.all() lo convierten en una herramienta indispensable cuando trabajas con múltiples tareas asíncronas en JavaScript. Como estás profundizando en este tema, es clave que entiendas no solo qué hace, sino cómo se comporta internamente.

Aquí tienes sus características principales explicadas para tu guía de estudio:

2.2.1. Ejecución en paralelo (Concurrencia)

Esta es su mayor ventaja técnica. En lugar de esperar a que termine una promesa para empezar la siguiente (secuencial), Promise.all() inicia todas las promesas del array al mismo tiempo.

  • Beneficio: El tiempo total de espera será igual al de la promesa más lenta, no a la suma de todas.

2.2.2. El estado «Todo o nada» (Fail-fast)

Promise.all() es extremadamente estricto.

  • Si todas las promesas se cumplen, la promesa principal se resuelve.
  • Si una sola promesa falla (se rechaza), Promise.all() se rechaza inmediatamente, ignorando el éxito de las demás. Es ideal para procesos donde necesitas el set de datos completo para poder trabajar (como cargar una configuración base).

2.2.3. Preservación del orden de los resultados

Aunque las promesas terminen en diferentes momentos (por ejemplo, la tercera termina antes que la primera), JavaScript reorganiza los resultados por ti.

  • Característica: El array de resultados que recibes en el .then() tendrá exactamente el mismo orden que el array de promesas que enviaste originalmente.
  • Ejemplo: Si enviaste [perfil, posts], el resultado siempre será [datosPerfil, datosPosts].

2.2.4. Recibe un iterable

No solo acepta arrays []. Puede recibir cualquier objeto iterable (como un Set o un Map), aunque en el 99% de los casos usarás arrays de promesas.

2.2.5. Manejo de valores «No-Promesa»

Si dentro del array pasas un valor que no es una promesa (como un número o un string), Promise.all() lo tratará como una promesa ya resuelta con ese valor. No dará error por mezclar tipos de datos.

2.3. Ejemplo para entender cómo funciona Promise.all()

El escenario práctico: Imagina que estás construyendo el panel de control (dashboard) de una tienda online. Cuando un cliente inicia sesión, necesitas mostrarle tres cosas importantes en la pantalla principal:

  1. Su información de perfil (nombre, email).
  2. Su historial de pedidos recientes.
  3. Los productos que dejó en su carrito de compras.

Hacer estas tres peticiones a la base de datos una por una (secuencialmente) haría que la página cargue muy lento. Aquí es donde Promise.all() brilla, permitiéndonos buscar las tres cosas al mismo tiempo (en paralelo) y mostrar la pantalla solo cuando toda la información esté lista.

El código:

// 1. Simulamos las peticiones a la base de datos o API externa.
// Cada función devuelve una Promesa que tarda un tiempo diferente en resolverse.

const cargarPerfilUsuario = () => {
  return new Promise((resolve) => {
    // Simulamos que la red tarda 1 segundo (1000 ms) en traer el perfil
    setTimeout(() => {
      resolve({ nombre: "Carlos", nivel: "Premium" });
    }, 1000);
  });
};

const cargarHistorialPedidos = () => {
  return new Promise((resolve) => {
    // Esta consulta es más pesada, tarda 3 segundos (3000 ms)
    setTimeout(() => {
      resolve(["Pedido #123", "Pedido #124"]);
    }, 3000);
  });
};

const cargarCarritoCompras = () => {
  return new Promise((resolve) => {
    // Esta es muy rápida, tarda medio segundo (500 ms)
    setTimeout(() => {
      resolve(["Teclado mecánico", "Ratón inalámbrico"]);
    }, 500);
  });
};

// 2. Usamos Promise.all() para ejecutar todas las peticiones al mismo tiempo
console.log("Cargando el panel de control, por favor espera...");

/* Le pasamos a Promise.all() un array con las EJECUCIONES de las funciones.
  Esto inicia las tres peticiones de forma simultánea.
*/
Promise.all([
  cargarPerfilUsuario(),   // Promesa 1 (1s)
  cargarHistorialPedidos(), // Promesa 2 (3s)
  cargarCarritoCompras()    // Promesa 3 (0.5s)
])
// 3. El bloque .then() se ejecuta SOLO cuando las tres promesas se cumplen con éxito
.then((resultados) => {
  /* 'resultados' es un array que respeta estrictamente el orden original:
    resultados[0] = datos del perfil
    resultados[1] = datos del historial
    resultados[2] = datos del carrito
  */
  const [perfil, pedidos, carrito] = resultados; // Desestructuración para leerlo mejor

  console.log("¡Carga completada con éxito!");
  console.log(`Bienvenido ${perfil.nombre} (${perfil.nivel}).`);
  console.log(`Tienes ${pedidos.length} pedidos anteriores.`);
  console.log(`Tienes ${carrito.length} artículos en tu carrito.`);
})
// 4. El bloque .catch() se ejecutaría si CUALQUIERA de las peticiones fallara
.catch((error) => {
  console.error("Hubo un error al cargar el panel:", error);
});
Lenguaje del código: JavaScript (javascript)

Explicación del resultado esperado:

Al ejecutar este código, el resultado en la consola será el siguiente:

  1. Inmediatamente aparecerá: "Cargando el panel de control, por favor espera...".
  2. Habrá una pausa de exactamente 3 segundos. (El tiempo que tarda la promesa más lenta, que es cargarHistorialPedidos).
  3. Después de esos 3 segundos, aparecerán de golpe todos los mensajes finales:
    • "¡Carga completada con éxito!"
    • "Bienvenido Carlos (Premium)."
    • "Tienes 2 pedidos anteriores."
    • "Tienes 2 artículos en tu carrito."

No tarda 4.5 segundos (la suma de 1s + 3s + 0.5s), porque se ejecutan a la vez. El sistema espera pacientemente al «más lento del grupo» para entregar todo el paquete junto.

💡 La Idea Clave que debes llevarte:
Promise.all() transforma la ejecución secuencial (esperar en fila) en ejecución paralela (todos avanzan a la vez), agrupando múltiples tareas asíncronas independientes. Su función principal es garantizarte que tienes todas las piezas del rompecabezas listas y en el orden correcto antes de permitirte dar el siguiente paso en tu código.

3. Promise.race()

Como su nombre lo indica (race = carrera), Promise.race() es un método estático que pone a competir a un grupo de promesas.

Este método devuelve una nueva promesa que se resuelve o se rechaza en el instante en que la primera promesa del iterable termina, sin importar si su resultado fue un éxito o un fracaso.

Imagina una carrera de 100 metros: el ganador es el primero que cruza la línea de meta. A Promise.race() solo le importa la velocidad, ignorando por completo qué pasa con el resto de las promesas una vez que ya hay un ganador.

3.1. Sintaxis y explicación

La estructura es idéntica a Promise.all(), ya que recibe un iterable (como un array) lleno de promesas, pero su comportamiento al procesar las respuestas es totalmente distinto.

/* Sintaxis básica de Promise.race */
Promise.race([promesaA, promesaB, promesaC])
  .then((resultadoGanador) => {
    // Se ejecuta si la promesa MÁS RÁPIDA se resolvió con éxito (resolve).
    // 'resultadoGanador' NO es un array. Es el valor único de esa primera promesa.
  })

  .catch((errorGanador) => {
    // Se ejecuta si la promesa MÁS RÁPIDA falló (reject).
    // 'errorGanador' es el motivo de rechazo de esa primera promesa.
  });Lenguaje del código: JavaScript (javascript)

¿Cómo funciona exactamente?

  1. Solo importa el primero:
    • En cuanto la promesa más rápida termina (ya sea cumpliéndose o siendo rechazada), Promise.race() adopta inmediatamente ese estado y ese valor.
  2. Las demás no se cancelan, pero se ignoran:
    • JavaScript no detiene la ejecución de las promesas más lentas en segundo plano, simplemente sus resultados o errores nunca llegarán al .then() o al .catch() de tu bloque Promise.race().
  3. No devuelve un array:
    • A diferencia de Promise.all(), aquí no hay que recolectar múltiples datos. Obtienes un único valor (el de la promesa ganadora).

3.2. Principales características de promise.race()

Las características de Promise.race() lo definen como el método más «competitivo» de JavaScript. A diferencia de Promise.all(), donde el objetivo es la cooperación, aquí el objetivo es la velocidad pura.

Aquí tienes las características principales que debes conocer para dominar este método:

3.2.1. El ganador se lo lleva todo (Determinismo por velocidad)

La característica más importante es que Promise.race() se resuelve o se rechaza en cuanto la primera promesa del array termina.

  • Si la primera en terminar tiene éxito, Promise.race() se resuelve con ese valor.
  • Si la primera en terminar falla, Promise.race() se rechaza con ese error.

3.2.2. No detiene las demás promesas

Es un error común pensar que Promise.race() cancela las promesas más lentas.

  • Característica: Las demás promesas siguen ejecutándose en segundo plano hasta que terminen, pero sus resultados son ignorados por el hilo principal. JavaScript simplemente deja de «escucharlas».

3.2.3. Estado de salida único

A diferencia de all o allSettled, este método no devuelve un array.

  • Característica: El valor que llega al .then() o al .catch() es un valor único (o un objeto de error único). Es exactamente el mismo resultado que produjo la promesa ganadora.

3.2.4. Sensibilidad al rechazo (Rechazo inmediato si es la más rápida)

Si tienes 5 promesas que van a tener éxito en 10 segundos, pero una sexta promesa falla en 1 segundo, Promise.race() se ejecutará como un error inmediatamente.

  • No espera a ver si alguna otra tiene éxito; si el primer evento que ocurre es un fallo, la carrera termina ahí.

3.2.5. Comportamiento con arrays vacíos

Esta es una característica técnica muy importante:

  • Si pasas un array vacío [] a Promise.all(), se resuelve inmediatamente.
  • Si pasas un array vacío [] a Promise.race(), la promesa se queda en estado pendiente (pending) para siempre. Esto ocurre porque nunca habrá una promesa que «gane» la carrera.

3.3. Ejemplo para entender cómo funciona Promise.race

El escenario práctico: Imagina que tu aplicación necesita obtener información vital de un servidor externo (por ejemplo, el clima actual o el precio de una criptomoneda). Sin embargo, el servidor a veces es muy lento o se queda «colgado». No quieres que tu usuario espere eternamente mirando una pantalla de carga.

Para solucionar esto, puedes crear una carrera: pones a competir la petición al servidor contra un temporizador (timeout) de, digamos, 3 segundos. Si el servidor responde antes de los 3 segundos, muestras los datos. Si el temporizador termina primero, cancelas la espera y muestras un mensaje de error diciendo que el tiempo de espera se agotó.

El código:

// 1. Simulamos la petición al servidor que intentará traer los datos.
const obtenerDatosDelServidor = new Promise((resolve, reject) => {
  // Simulamos que el servidor es lento y tarda 5 segundos (5000 ms) en responder.
  setTimeout(() => {
    resolve({ status: 200, data: "Aquí están los datos solicitados" });
  }, 5000);
});

// 2. Creamos una promesa que actúa como nuestro temporizador límite.
const limiteDeTiempo = new Promise((resolve, reject) => {
  // Esta promesa siempre será rechazada (reject) después de 3 segundos (3000 ms).
  setTimeout(() => {
    reject(new Error("El tiempo de espera se ha agotado (Timeout)"));
  }, 3000);
});

// 3. ¡Iniciamos la carrera! Pasamos ambas promesas en un array a Promise.race()
console.log("Solicitando datos al servidor...");

Promise.race([obtenerDatosDelServidor, limiteDeTiempo])
  .then((resultadoGanador) => {
    /* Si 'obtenerDatosDelServidor' fuera más rápida (por ejemplo, si tardara 2s),
       entraríamos a este bloque .then() e ignoraríamos el temporizador.
       'resultadoGanador' sería el objeto con los datos.
    */
    console.log("✅ Éxito:", resultadoGanador.data);
  })
  .catch((errorGanador) => {
    /* Como 'limiteDeTiempo' tarda 3s y el servidor tarda 5s,
       el temporizador GANA la carrera. Por lo tanto, Promise.race adopta
       el estado de rechazo y entra en este bloque .catch().
    */
    console.error("❌ Falló la operación:", errorGanador.message);
  });Lenguaje del código: JavaScript (javascript)

Explicación del resultado esperado:

Al ejecutar este código, verás lo siguiente en la consola:

  1. Inmediatamente aparecerá: "Solicitando datos al servidor...".
  2. Habrá una pausa de 3 segundos.
  3. Pasados esos 3 segundos, aparecerá el error: "❌ Falló la operación: El tiempo de espera se ha agotado (Timeout)".

Llegamos a este resultado porque Promise.race() evaluó ambas promesas simultáneamente. El temporizador (3 segundos) cruzó la línea de meta antes que la respuesta del servidor (5 segundos). Como el temporizador era una promesa rechazada (reject), todo el bloque de Promise.race() se rechaza instantáneamente y salta al bloque .catch(). Los datos del servidor, que llegarían a los 5 segundos, simplemente se pierden en el vacío; a JavaScript ya no le importan porque la carrera ya terminó.

4. Promise.allSettled()

Promise.allSettled() es un método estático que se introdujo para solucionar el problema del «todo o nada» de Promise.all(). Su función es esperar a que todas las promesas del array terminen, sin importar si tuvieron éxito (fulfilled) o si fallaron (rejected).

A diferencia de los otros métodos, este nunca se interrumpe por un error. Siempre llega al final de la lista y te entrega un reporte detallado del estado de cada una de las operaciones. Es como un supervisor que hace una lista de asistencia y anota quién llegó a trabajar y quién tuvo un problema, pero no cancela la jornada si alguien falta.

4.1. Sintaxis y explicación

La sintaxis sigue el patrón de los métodos de la clase Promise, recibiendo un iterable (un array) y devolviendo una única promesa.

/* Sintaxis básica de Promise.allSettled */
Promise.allSettled([promesa1, promesa2, promesa3])
  .then((resultados) => {
    /* 'resultados' SIEMPRE será un array de objetos.
       Cada objeto tiene una estructura fija:
       Si tuvo éxito: { status: "fulfilled", value: valor }
       Si falló:      { status: "rejected", reason: error }
    */
  });Lenguaje del código: JavaScript (javascript)

¿Cómo funciona internamente? (Reglas clave)

  1. Paciencia total:
    • No importa si la primera promesa falla a los 10ms; el método esperará a que la última promesa (aunque tarde 5 segundos) termine para darte el resultado global.
  2. Resultado Estructurado:
    • El array que devuelve contiene objetos que te permiten filtrar fácilmente qué funcionó y qué no. Nunca saltará al bloque .catch() por un fallo en las promesas del array; solo entraría al .catch() si hubiera un error de sintaxis grave en tu código.
  3. Ideal para tareas independientes:
    • Es la herramienta perfecta cuando tienes varias tareas que no dependen entre sí. Por ejemplo, si estás actualizando 5 plugins en WordPress, quieres saber cuáles se actualizaron y cuáles dieron error, en lugar de que falle todo el proceso porque uno solo falló.

4.2. Características principales de promise.allSettled()

Aquí tienes las características principales que lo hacen único:

4.2.1. Resiliencia total (No hay «Fail-Fast»)

Esta es su característica estrella. Mientras que otros métodos cancelan todo si una promesa falla, Promise.allSettled() espera a que todas las promesas terminen, ya sea que se resuelvan con éxito o se rechacen.

  • Beneficio: Te permite ejecutar múltiples tareas independientes sin que el fallo de una arruine el resultado de las demás.

4.2.2. Estructura de respuesta predictible

A diferencia de otros métodos que devuelven solo los valores, este siempre devuelve un array de objetos. Cada objeto describe el destino final de cada promesa con una estructura fija:

  • Si tuvo éxito: { status: "fulfilled", value: valor_de_la_promesa }
  • Si falló: { status: "rejected", reason: motivo_del_error }

4.2.3. Orden garantizado

Al igual que Promise.all(), el array de resultados que obtienes sigue estrictamente el mismo orden en el que pasaste las promesas originalmente. Esto te permite saber exactamente a qué tarea corresponde cada éxito o cada error.

4.2.4. Ejecución en paralelo

Lanza todas las promesas simultáneamente. El tiempo total que tardará en ejecutarse será igual al tiempo de la promesa más lenta del grupo, ya que debe esperar a que la última «se asiente» (settled) para darte el informe final.

4.2.5. Casi nunca cae en el .catch()

Dado que el propósito del método es informarte sobre los fallos dentro del array de resultados, es muy raro que Promise.allSettled() lance una excepción propia.

  • Solo entraría al .catch() si hubiera un error crítico en el código (como pasar algo que no es un iterable) o si el motor de JavaScript se queda sin memoria, pero no por el rechazo de las promesas que está vigilando.

4.3. Ejemplo para entender cómo funciona Promise.allSettled()

El escenario práctico: Imagina que eres el administrador de un sitio web en WordPress y tienes un script que debe enviar un correo electrónico de bienvenida a una lista de 3 nuevos suscriptores.

  • Si usaras Promise.all(), y el correo del segundo usuario falla (por un error en su dirección, por ejemplo), el sistema se detendría y no enviaría el tercero.
  • Con Promise.allSettled(), el sistema intentará enviar los tres correos. Al final, te entregará un reporte detallado para que sepas exactamente a quién se le envió con éxito y quién falló, permitiéndote reintentar solo los errores sin duplicar los envíos exitosos.

El código:

// 1. Simulación de la función de envío de correos.
// Recibe un nombre y decide si tiene éxito o falla para el ejemplo.
const enviarEmail = (usuario) => {
  return new Promise((resolve, reject) => {
    const tiempo = Math.random() * 2000; // Tiempo de red aleatorio
    setTimeout(() => {
      if (usuario === "Usuario_Error") {
        reject(`Error: El servidor de correo rechazó a ${usuario}`);
      } else {
        resolve(`Email enviado con éxito a ${usuario}`);
      }
    }, tiempo);
  });
};

// 2. Definimos nuestra lista de tareas (promesas)
const listaDeEnvios = [
  enviarEmail("Ana"),
  enviarEmail("Usuario_Error"), // Este provocará un fallo
  enviarEmail("Pedro")
];

console.log("Iniciando envío masivo de correos...");

// 3. Usamos Promise.allSettled() para procesar la lista completa
/* Este método esperará a que los 3 intentos terminen, 
   sin importar que el segundo falle.
*/
Promise.allSettled(listaDeEnvios)
  .then((reporte) => {
    /* 'reporte' es un array de objetos con el resultado de cada envío.
       Usamos forEach para recorrer el informe final.
    */
    reporte.forEach((resultado, indice) => {
      if (resultado.status === "fulfilled") {
        // Bloque para los éxitos
        console.log(`✅ Tarea ${indice + 1}: ${resultado.value}`);
      } else {
        // Bloque para los fallos (captura el reject sin romper el código)
        console.log(`❌ Tarea ${indice + 1}: ${resultado.reason}`);
      }
    });
    
    console.log("Proceso finalizado. Revisa el reporte de errores arriba.");
  });Lenguaje del código: JavaScript (javascript)

Explicación del resultado esperado:

Al ejecutar este código, verás un comportamiento muy organizado en la consola:

  1. Aparecerá el mensaje inicial de carga.
  2. Tras un par de segundos (cuando la promesa más lenta termine), verás el desglose:
    • ✅ Tarea 1: Email enviado con éxito a Ana
    • ❌ Tarea 2: Error: El servidor de correo rechazó a Usuario_Error
    • ✅ Tarea 3: Email enviado con éxito a Pedro
  3. Finalmente: "Proceso finalizado. Revisa el reporte de errores arriba."

Llegamos a este resultado porque Promise.allSettled() no tiene «pánico» ante los errores. Acepta el fallo de la Tarea 2, lo guarda en un objeto con la propiedad status: "rejected" y sigue trabajando con la Tarea 3. Al final, te entrega todas las piezas para que tú decidas qué hacer con los fallos.

💡 La Idea Clave que debes llevarte:
La función principal de Promise.allSettled() es la gestión de reportes y resiliencia. Se usa cuando las tareas son independientes entre sí. Te asegura que una «manzana podrida» (un error) no arruine todo el cesto, dándote un informe transparente de qué ocurrió en cada paso de tu proceso asíncrono.

5. Promise.any()

Promise.any() es un método estático que actúa como el «optimista» del grupo de promesas. Su funcionamiento es sencillo: recibe un array de promesas y se resuelve en cuanto la primera de ellas tenga éxito (se cumpla).

A diferencia de Promise.race(), que se detiene con el primero que termine (sea éxito o error), Promise.any() ignora los errores iniciales. Solo si todas las promesas del array fallan, entonces el método se rechaza. Es ideal para situaciones donde tienes varias fuentes para obtener lo mismo y solo necesitas que una funcione.

5.1. Sintaxis y explicación

La estructura sigue el estándar de los métodos de la clase Promise, devolviendo una única promesa basada en la primera que se resuelva satisfactoriamente.

/* Sintaxis básica de Promise.any */
Promise.any([promesa1, promesa2, promesa3])
  .then((primerValorExitoso) => {
    // Se ejecuta en cuanto la PRIMERA promesa del array se cumpla (resolve).
    // 'primerValorExitoso' es el valor de esa promesa ganadora.
  })

  .catch((errorGlobal) => {
    // Se ejecuta SOLO si TODAS las promesas fueron rechazadas.
    // 'errorGlobal' es un objeto especial llamado AggregateError.
  });Lenguaje del código: JavaScript (javascript)

¿Cómo funciona exactamente? (Reglas clave)

  1. Búsqueda del primer éxito:
    • No importa si la primera promesa falla en 1 milisegundo; Promise.any() seguirá esperando a que alguna otra tenga éxito.
  2. Ignora los rechazos individuales:
    • Los errores que ocurran en el camino son descartados silenciosamente, a menos que no quede ninguna promesa viva en el array.
  3. El AggregateError:
    • Si todas las promesas fallan, el bloque .catch() recibe un AggregateError. Este es un objeto especial que contiene una propiedad llamada .errors, la cual es un array con todos los motivos de rechazo de cada promesa que falló.
  4. No devuelve un array:
    • Al igual que race, obtienes un único valor: el de la primera promesa que logró completarse.

5.2. Características principales de Promise.any()

Aquí tienes las características clave que lo distinguen:

5.2.1. Búsqueda del primer éxito (First-fulfilled)

Esta es su razón de ser. Promise.any() se resuelve en cuanto la primera promesa del array se cumple con éxito (resolve).

  • Diferencia con Race: Si la primera promesa en terminar falla, Promise.any() no se rinde; ignora ese error y sigue esperando a la siguiente que sí funcione.

5.2.2. Tolerancia a fallos parciales

Es el método más permisivo. Puedes tener un array de 10 promesas donde 9 fallan, y si la número 10 tiene éxito, Promise.any() se resolverá correctamente con ese valor.

  • Característica: Los errores individuales son «silenciados» automáticamente mientras quede alguna promesa pendiente que pueda tener éxito.

5.2.3. El error de grupo (AggregateError)

¿Qué pasa si todas las promesas fallan? Aquí es donde aparece una característica única de este método:

  • AggregateError: En lugar de devolver un solo error, devuelve un objeto especial que agrupa todos los errores de todas las promesas que fallaron.
  • Puedes acceder a ellos mediante la propiedad .errors (que es un array con cada motivo de rechazo).

5.2.4. Ejecución en paralelo y Redundancia

Al igual que sus «hermanos», lanza todas las peticiones al mismo tiempo.

  • Uso ideal: Es perfecto para sistemas de redundancia. Por ejemplo, si tienes tres servidores espejos (Mirror A, B y C) con la misma información, usas Promise.any() para mostrar los datos del primero que responda bien, ignorando si alguno está caído.

5.2.5. Resultado de valor único

No devuelve un array de resultados.

  • Característica: Al igual que Promise.race(), el resultado final en el .then() es únicamente el valor de la promesa que ganó la carrera del éxito.

5.3. Ejemplo para entender cómo funciona Promise.any()

El escenario práctico: Imagina que eres un desarrollador y tu aplicación necesita descargar un archivo de configuración importante. Para asegurar que el usuario no tenga problemas, tienes el archivo guardado en tres servidores diferentes (un «espejo» en EE. UU., otro en Europa y otro en Asia).

No te importa de cuál servidor venga el archivo, solo quieres el primero que responda correctamente. Si el servidor de EE. UU. está caído (da error), no quieres que la aplicación falle; quieres que ignore ese error y espere al de Europa o Asia. Solo si los tres servidores fallan, le avisarás al usuario que hay un problema de conexión.

El código:

// 1. Simulamos las peticiones a tres servidores distintos (mirrors)
const peticionServidorEEUU = new Promise((resolve, reject) => {
  // Simulamos que este servidor falla rápido (un error 500)
  setTimeout(() => reject("Error 500: Servidor EE.UU. caído"), 500);
});

const peticionServidorEuropa = new Promise((resolve, reject) => {
  // Simulamos que este servidor funciona pero es algo lento (2 segundos)
  setTimeout(() => resolve("Configuración desde Europa cargada ✅"), 2000);
});

const peticionServidorAsia = new Promise((resolve, reject) => {
  // Simulamos que este también funciona y tarda 3 segundos
  setTimeout(() => resolve("Configuración desde Asia cargada ✅"), 3000);
});

// 2. Iniciamos la búsqueda con Promise.any()
console.log("Buscando servidor disponible...");

/* Promise.any() ignorará el rechazo de EE.UU. porque busca el primer ÉXITO.
   Se resolverá en cuanto Europa (el siguiente más rápido en funcionar) termine.
*/
Promise.any([peticionServidorEEUU, peticionServidorEuropa, peticionServidorAsia])
  .then((resultado) => {
    // Este bloque se ejecuta con el primer mensaje de éxito que llegue
    console.log("Resultado final:", resultado);
  })
  .catch((errorGlobal) => {
    /* Este bloque SOLO se ejecutaría si los TRES servidores fallaran.
       errorGlobal sería un 'AggregateError' con todos los fallos.
    */
    console.error("Ningún servidor pudo entregar el archivo:", errorGlobal.errors);
  });Lenguaje del código: JavaScript (javascript)

Explicación del resultado esperado:

Al ejecutar este código, el flujo en la consola será el siguiente:

  1. Primero verás: "Buscando servidor disponible...".
  2. A los 0.5 segundos, el servidor de EE. UU. falla. Promise.any() ignora esto y no muestra nada aún, sigue esperando.
  3. A los 2 segundos, el servidor de Europa responde con éxito.
  4. Inmediatamente verás el mensaje: "Resultado final: Configuración desde Europa cargada ✅".
  5. La petición de Asia (que tardaba 3 segundos) se ignora por completo porque ya tenemos un ganador exitoso.

Llegamos a este resultado porque la prioridad de Promise.any() es la supervivencia del proceso. A diferencia de Promise.race(), que habría fallado a los 0.5 segundos al ver el primer error, any() tiene la «paciencia» de esperar a que alguien haga bien el trabajo.

💡 La Idea Clave que debes llevarte:
La función principal de Promise.any() es la tolerancia a fallos y la redundancia. Se usa cuando tienes múltiples fuentes para obtener un mismo recurso y quieres que tu código sea robusto. Es el método «optimista» porque asume que, mientras una sola opción funcione, la operación global es un éxito.

Deja un comentario

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