くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

TypeScriptのPromiseでretryしたい(async-retry/node-retry)

TypeScriptのPromiseでretryしたいなと思って、
いろいろ調べたときの備忘録。

vercelが公開してるasync-retryがよさそう。
vercel/async-retry: Retrying made simple, easy and async

中身は60行ほどで、node-retryを使っている感じ。

tim-kos/node-retry: Abstraction for exponential and custom retry strategies for failed operations.

使い方

公式のサンプルをベースに。使い方はこんな感じ。

// Packages
const retry = require('async-retry');
const fetch = require('node-fetch');

await retry(
  // 対象の関数
  async (bail, num) => {
    const res = await fetch('https://google.com');

    if (403 === res.status) {
      // 403のときはリトライしない
      bail(new Error('Unauthorized'));
      return;
    }

    return await res.text();
  },
  // オプション
  {
    // 最大リトライ回数
    retries: 10,
    // 指数関数的バックオフのfactor
    factor: 2,
    // 初回の待ち時間
    minTimeout: 1000,
    // 最大の待ち時間
    maxTimeout: Infinity,
    // ランダム化時の係数(1~2)
    randomize: true,
    // リトライ時に呼ばれる関数
    onRetry: (err, num) => console.log(err, num),
  }
);

オプションの大部分は、node-retryのオプション。
tim-kos/node-retry: Abstraction for exponential and custom retry strategies for failed operations.

リトライ時の待ち時間は以下の式で計算される。

Math.min(random * minTimeout * Math.pow(factor, attempt), maxTimeout)

以上!! 便利(´ω`)

参考にしたサイト様