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

387
Views
¿Es esta la forma correcta de escribir un bucle while sin bloqueo usando try-catch, setTimeout y recursión?

Tengo un punto final en mi servidor llamado "/order".

Cuando se activa, necesito enviar un pedido a una API. A veces, debido a que algunos datos a través de ipfs tardan demasiado en descargarse, el pedido falla dentro del bloque try-catch y necesito volver a enviarlo.

Dado que un bucle while que intenta reenviar la orden hasta que tenga éxito estaría bloqueando otras solicitudes, pensé que podría hacer uno yo mismo usando recursividad y setTimeout, para intentar enviar la misma solicitud, digamos, 3 veces cada 5 minutos y si la tercera vez que falla, entonces no lo intentará de nuevo.

Quería saber si esta era la forma correcta de lograr la funcionalidad sin bloqueo y si hay algunas vulnerabilidades/cosas que no estoy teniendo en cuenta:

 async function makeOrder(body, tries) { if (tries > 0) { let order; try { order = getOrderTemplate(body.shipping_address) for (const index in body.line_items) { order.items.push(await getItemTemplate(body.line_items[index])) } await sendOrderToAPI(order) } catch (err) { setTimeout(function(){ makeOrder(body, tries - 1) }, 180000) } } else { console.log("order n " + body.order_number + " failed") //write failed order number to database to deal with it later on } }
about 4 years ago · Santiago Gelvez
1 answers
Answer question

0

Un problema importante es que, si hay un problema, devolverá una Promesa que no se resuelve cuando finaliza la llamada API final, sino cuando finaliza la llamada API inicial (fallida). Este:

 setTimeout(function(){ makeOrder(body, tries - 1) }, 180000)

no está encadenado correctamente con la función async externa.

Como resultado, la siguiente lógica fallará:

 makeOrder(body, 3) .then(() => { // All orders are made })

En su lugar, prométalo, de modo que la llamada recursiva se pueda encadenar fácilmente con la función externa.

 const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); async function makeOrder(body, tries) { if (tries > 0) { let order; try { order = getOrderTemplate(body.shipping_address) for (const index in body.line_items) { order.items.push(await getItemTemplate(body.line_items[index])) } await sendOrderToAPI(order) } catch (err) { await delay(180_000); return makeOrder(body, tries - 1); } } else { console.log("order n " + body.order_number + " failed") //write failed order number to database to deal with it later on } }

Otra posible mejora sería, en lugar de await dentro de un bucle aquí:

 for (const index in body.line_items) { order.items.push(await getItemTemplate(body.line_items[index])) }

para usar Promise.all , o un mecanismo diferente que permita obtener varias plantillas a la vez, en lugar de tener que esperar una por una en serie.

Otro problema potencial es que makeOrder no rechaza cuando excede el número de intentos permitidos. Es decir, el consumidor no podría hacer:

 makeOrder(body, 3) .catch((error) => { // implement logic here to handle the error })

Si desea permitir lo anterior, al final de makeOrder , ejecute al mismo tiempo que está iniciando sesión:

 } else { console.log("order n " + body.order_number + " failed") //write failed order number to database to deal with it later on throw new Error('Failed'); }
about 4 years ago · Santiago Gelvez 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!