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

293
Views
Promise.allSettled(): estrategia de reintento para varias llamadas asincrónicas

TL; DR: estoy buscando una estrategia o un ejemplo de manejo de una cantidad desconocida de rechazos de promesas y volver a intentarlos una cantidad de tiempo X cuando uso Promise.allSettled() para múltiples llamadas asíncronas.

Después de leer este artículo: https://www.coreycleary.me/better-handling-of-rejections-using-promise-allsettled Me emocioné mucho con esta oración:

Esto es excelente porque aún podemos cargar la información de la cuenta del usuario y volver a intentar recuperar la actividad del usuario más tarde. (los reintentos están fuera del alcance de esta publicación, y existen múltiples estrategias para eso)

Sin embargo, cuando investigué en línea, no encontré absolutamente ningún ejemplo concreto, o incluso publicaciones que traten este tema directamente.

Aquí hay un código de ejemplo:

 public async test() { try { console.log('trying..'); const multiAsync = [this.somethingA(), this.somethingB(), this.somethingC()]; const [a, b, c] = await Promise.allSettled(multiAsync); } catch (e) { console.log('catch'); console.log(e); } }

Ahora digamos que para el código anterior, tanto A como C fallaron, y quiero volver a intentarlos, digamos, solo una vez más. Aunque tengo a, b, c , solo sé cuál se fullfilled:true y cuál no. pero no sé vincular a back to somethingA() y c to somethingC() para volver a intentar solo esas 2 funciones, y definitivamente no quiero invocar somethingB() dos veces.

¿Algunas ideas?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Las Promesas no guardan ningún registro de su origen: una vez que tienes una Promesa, no hay nada que te permita volver a intentar su origen varias veces. Como tal, los patrones comunes de reintento de Promise aceptan la función de devolución de promesas ("fábrica de promesas"), no solo la Promesa en sí. Envolver cada promesa individual en una función de reintento como esta antes de llamar a all o allSettled es la solución más práctica , ya que las promesas que fallan rápidamente pueden volver a intentarlo de inmediato sin esperar la lista completa como lo hace allSettled .

 const multiAsync = [ retry(() => this.somethingA(), 3), retry(() => this.somethingB(), 3), retry(() => this.somethingC(), 3), ]; const [a, b, c] = await Promise.allSettled(multiAsync); // or const [a, b, c] = await Promise.allSettled([/* functions */].map(x => retry(x, 3));

Sin embargo, si desea ver cómo usar Promise.allSettled para hacer esto directamente, tengo uno aquí. Mi solución aquí no respeta los tiempos de espera, que puede agregar de forma global o individual con una implementación de Promise.race .

 /** * Resolves a series of promise factories, retrying if needed. * * @param {number} maxTryCount How many retries to perform. * @param {Array<() => Promise<any>>} promiseFactories Functions * that return promises. These must be functions to enable retrying. * @return Corresponding Promise.allSettled values. */ async function allSettledWithRetry(maxTryCount, promiseFactories) { let results; for (let retry = 0; retry < maxTryCount; retry++) { let promiseArray; if (results) { // This is a retry; fold in results and new promises. promiseArray = results.map( (x, index) => x.status === "fulfilled" ? x.value : promiseFactories[index]()) } else { // This is the first run; use promiseFactories only. promiseArray = promiseFactories.map(x => x()); } results = await Promise.allSettled(promiseArray); // Avoid unnecessary loops, though they'd be inexpensive. if (results.every(x => x.status === "fulfilled")) { return results; } } return results; } /* test harness below */ function promiseFactory(label) { const succeeds = Math.random() > 0.5; console.log(`${label}: ${succeeds ? 'succeeds' : 'fails'}`); return succeeds ? Promise.resolve(label) : Promise.reject(new Error(`Error: ${label}`)); } allSettledWithRetry(5, [ () => promiseFactory("a"), () => promiseFactory("b"), () => promiseFactory("c"), () => promiseFactory("d"), () => promiseFactory("e"), ]).then(console.log);

about 4 years ago · Juan Pablo Isaza Report

0

Esto funcionó bien conmigo.

 export const allSettledWithRetries = async ( promises: Promise<FixMeLater>[], retries: number, waitBetweenRetries = 1000 ): Promise<FixMeLater[]> => { const results = await Promise.allSettled(promises); const successResponses: FixMeLater[] = []; results.forEach((promiseResult) => { if (promiseResult.status === 'fulfilled') { successResponses.push(promiseResult.value); } }); if (retries > 0 && successResponses.length !== promises.length) { const failedPromises: Promise<FixMeLater>[] = []; results.forEach((promiseResult, index) => { if (promiseResult.status === 'rejected') { failedPromises.push(promises[index]); } }); logger.warn(`failed to run ${failedPromises.length} and will try again`); // eslint-disable-next-line no-promise-executor-return await new Promise((resolve) => setTimeout(resolve, waitBetweenRetries)); const failedResults = await allSettledWithRetries( failedPromises, retries - 1 ); failedResults.forEach((promiseResult) => { if (promiseResult.status === 'fulfilled') { successResponses.push(promiseResult.value); } }); } return successResponses; };
about 4 years ago · Juan Pablo Isaza 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!