typestar

Reintentos con backoff en JavaScript

Volver a intentar, esperando más cada vez, y rendirse en algún momento.

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function retry(work, { attempts = 4, base = 5 } = {}) {
  let lastError;
  for (let attempt = 1; attempt <= attempts; attempt += 1) {
    try {
      return await work(attempt);
    } catch (error) {
      lastError = error;
      if (attempt === attempts) break;
      await sleep(base * 2 ** (attempt - 1));
    }
  }
  throw new Error(`failed after ${attempts} attempts`, { cause: lastError });
}

async function main() {
  const value = await retry(async (attempt) => {
    if (attempt < 3) throw new Error(`attempt ${attempt} failed`);
    return "succeeded";
  });
  console.log(value);

  const failed = await retry(async () => {
    throw new Error("always");
  }, { attempts: 2 }).catch((e) => e);
  console.log(failed.message, "|", failed.cause.message);
}

main();

Cómo funciona

  1. La espera se duplica; eso es lo que significa backoff.
  2. Reintenta solo lo que valga la pena reintentar.
  3. Adjunta el último error como causa al rendirte.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
30
Caracteres a escribir
787
Tokens
232
Ritmo de tres estrellas
110 tpm

Al ritmo de tres estrellas de 110 tokens por minuto, este intento toma unos 127 segundos.

Escribe este fragmento

Paso 3 de 4 en Cancelar y limitar; paso 17 de 19 en Promesas y async.

← Anterior Siguiente →