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

121
Vistas
Racing web request promises recursively

I have a web request that sometimes completes in .1 seconds, and sometimes completes in 20 seconds. My solution is to send requests with a timeout. When the timeout triggers, I want to send another request. However, I want to leave the previous request open, and race it against the new request. I want to do this until one of the open requests completes, ending the race for all open requests.
I'm also open to suggestions for an alternative approach to this problem.

const timeoutLimit = 300;
const timeoutMessage = 'Response timed out';

/** Executes a request, retrying on timeouts, until it returns successfully. */
export default async function requestWithTimeout(request, count) {
  const timeout = new Promise((resolve, reject) => {
    setTimeout(() => reject(timeoutMessage), timeoutLimit);
  });

  const apiCall = new Promise((resolve, reject) => {
    request
      .catch((err) => reject(err))
      .then((resp) => resolve(resp));
  });

  count += 1;

  const result = await Promise.race([apiCall, timeout])
    .catch((err) => {
      console.log(err, count);
      return (err === timeoutMessage) ? Promise.race([apiCall, requestWithTimeout(request, count)]) : err;
    })
    .then((val) => {
      console.log('returned', count);
      return val;
    });

  console.log(count, result);

  return result;
}

Here is an example of the output from the console: print statements indicating timeout and response order

I always get things printed in this order:

Response timed out 1
Response timed out 2
returned 1
returned 2
returned 3
data 1
data 2
data 3

But I want my response to be something like this:

Response timed out 1
Response timed out 2
returned 1
data 1
returned 3
data 3
returned 2
data 2
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

My solution was to use an array to keep track of pending promises. In this way, I can open a request, and race it against the previous, still pending requests that lost a race against a timeout promise. The races will end whenever one of the pending request promises is fulfilled. This will slowly build an array of requests every timeout period, until one of them is fulfilled. By slowly increasing the number of concurrent requests instead of discarding them after the timeout period, I want to increase the likelihood that one of the requests is fulfilled by my server with an erratic response time.

const timeoutLimit = 250;
const timeoutLimitMessage = 'Response timed out, retrying';
const requestLimit = 20;
const RequestLimitMessage = 'Too many requests';

/** Executes a request, retrying on timeouts, until it returns successfully. */
export default async function requestWithTimeout(request, promises = []) {
  const timeout = new Promise((resolve, reject) => {
    setTimeout(() => reject(timeoutLimitMessage), timeoutLimit);
  });

  const apiCall = new Promise((resolve, reject) => {
    request
      .catch((err) => reject(err))
      .then((resp) => resolve(resp));
  });

  promises.push(apiCall);

  const result = await Promise.race([...promises, timeout])
    .catch((err) => {
      if (err !== timeoutLimitMessage) {
        return err;
      }
      console.log(timeoutLimitMessage);
      if (promises.length > requestLimit) {
        throw new Error(RequestLimitMessage);
      }
      return Promise.race([...promises, requestWithTimeout(request, promises)]);
    })
    .then((resp) => resp);

  return result;
}
about 4 years ago · Juan Pablo Isaza 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