Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

244
Vistas
Cómo detener la ejecución de Promise.map después de un error con Bluebird

Tengo una gran cantidad de datos para crear en la base de datos y quiero generarlos en paralelo con un límite de concurrencia. Para hacer eso, estoy usando el método Promise.map de bluebird con el límite de concurrency establecido. Sin embargo, también necesito detener la ejecución de la cadena tan pronto como falle una de las promesas.

Este es mi código actual:

 await Promise.map( entry.tags, async (tag) => { await factory(Tag)().create(tag); }, { concurrency: 1000 }, ).catch(() => { /** @todo find a better way */ process.exit(1); });

Por el momento, como puede ver, estoy usando process.exit(1) pero no manejaría el código de salida allí. En su lugar, la cadena Promise debería detenerse instantáneamente y el error debería lanzarse para ser detectado por la función principal.

Con la biblioteca p-map , existe el parámetro "stopOnError" que funciona exactamente como espero, no puedo encontrar nada similar en Bluebird. También intenté usar el método .cancel() dentro de .catch() pero aparentemente no funciona.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Su cadena de promesa se detiene instantáneamente y generaría un error en su función de llamada. Sin embargo, dos cosas están sucediendo aquí:

  1. Le está diciendo a Bluebird que ponga en cola hasta 1000 Promesas en paralelo, y una vez que se crea una Promesa, no hay forma significativa de cancelarla. Puede ver que ~999 Promesas tienen un efecto incluso después de que una falla, debido a su límite de simultaneidad de 1000.
  2. Al llamar a .catch en su Promesa, está manejando un await que, de lo contrario, se convertiría en el error que desea.

Vea este violín , ya que Stack Snippets no es compatible con Bluebird:

 (async function() { try { await Promise.map( seq(100), (i) => { console.log(i); if (Math.random() > 0.5) return Promise.resolve(); else return Promise.reject(); }, { concurrency: 5 }, ).catch(() => { console.error("catch 1"); }); } catch(e) { console.error("catch 2"); } })(); function seq(i) { return Array(i).keys(); }

A medida que se ejecuta el código, verá el registro de "captura 1" pero no "captura 2", porque el bloque catch hace que la promesa externa se resuelva en lugar de rechazarla . También notará que se imprimen menos de 100 números en la salida; de hecho, menos de 5 se imprimen a la salida, ya que Bluebird deja de mapear lo antes posible, y en este ejemplo, la Promesa falla lo suficientemente rápido como para que Bluebird ni siquiera tenga la oportunidad de llenar a todos los trabajadores concurrentes. En su código real, que presumiblemente es asíncrono, es posible que vea que la mayoría o todos sus 1000 trabajadores comienzan antes de que alguno de ellos falle lo suficientemente rápido como para cancelar.

Puede reducir su parámetro de concurrencia si desea que se realicen menos intentos a la vez, pero nuevamente, no hay una forma garantizada de cancelar Promises en Javascript. Incluso en Bluebird, que admite un método de cancelación de Promise , "cancelar una promesa simplemente significa que no se llamará a las devoluciones de llamada de su controlador". Esta semántica, que el documento etiqueta como semántica de "no importa" en contraste con la semántica de "abortar", es redundante para la semántica que Promise.map ya le proporciona.

Con respecto al bloque de catch : si eliminara la llamada de catch que rodea a mi "captura 1", fallaría en "captura 2" en el bloque de try externo, equivalente a detectar el error en la función principal como prefiera. Como alternativa, el bloque catch de Promise podría volver a generar el motivo de rechazo, lo que haría que tanto "captura 1" como "captura 2" se impriman en sus registros:

 ).catch((t) => { console.error("catch 1"); return Promise.reject(t); });
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda