• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

327
Vistas
¿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 3 years ago · Santiago Gelvez
1 Respuestas
Responde la pregunta

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 3 years ago · Santiago Gelvez 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 Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda