Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

240
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!