JavaScriptでリトライ処理を実装する方法!

この記事では『JavaScriptでリトライ処理を実装する方法』について、以下の内容をサンプルコードを用いてわかりやすく解説します。

  • リトライ処理とは
  • JavaScriptでリトライ処理を実装する方法
    • エクスポネンシャルバックオフを採用する

リトライ処理とは

リトライ処理は、何らかの理由で失敗した操作を自動的に再試行する仕組みです。

リトライ処理は特に、ネットワークエラーや一時的なサーバエラーなど一時的な問題が原因で発生するエラーに対処する場合に役立ちます。

例えば、外部APIを呼び出す際、通信が不安定で一度の試行で成功しないことがあります。このような場合にリトライ処理を組み込むことで、問題が解消されたタイミングで再度試行し、最終的に成功する可能性を高めることができます。

JavaScriptでリトライ処理を実装する方法

固定の遅延時間でリトライするシンプルなリトライ処理のサンプルコードを以下に示します。

async function simpleRetry(maxRetries, delay, operation) {
  let retryCount = 0; // 内部でリトライカウントを管理
  while (retryCount < maxRetries) {
    try {
      // 非同期操作を試行
      const result = await operation();
      return result;
    } catch (error) {
      retryCount++;
      if (retryCount >= maxRetries) {
        throw new Error(`リトライ回数が最大回数(${maxRetries})に達しました: ${error.message}`);
      }
      console.log(`${delay}ms待ってリトライします`);
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }
}

// 使用例
const exampleOperation = async () => {
  // 失敗する可能性のある処理を記述
  const randomNumber = Math.random();
  console.log('randomNumber: ', randomNumber);
  if (randomNumber > 0.7) {
    return 'Success';
  } else {
    throw new Error('Failure');
  }
};

simpleRetry(5, 1000, exampleOperation)
  .then((result) => console.log(`処理が成功しました: ${result}`))
  .catch((error) => console.error(error.message));

simpleRetry関数は、最大maxRetries回まで非同期操作を試行します。失敗するたびに指定されたdelay(ミリ秒)だけ待機します。exampleOperationはランダムな値を生成し、その値が0.7以上なら成功、そうでなければ失敗します。リトライ処理を通じて、この操作を最大5回試行します。

エクスポネンシャルバックオフを採用する

リトライ処理の実装には、「エクスポネンシャルバックオフ」という戦略がよく用いられます。

エクスポネンシャルバックオフは、処理が失敗した際、再試行(リトライ)までの待機時間を指数関数的に増加させる方法です。最初は短い間隔でリトライを試みますが、失敗が続くと待機時間が徐々に長くなります。その結果、サーバの負荷を軽減することができます。

エクスポネンシャルバックオフを採用したサンプルコードを以下に示します。

async function exponentialBackoff(maxRetries, delay, operation) {
  let retryCount = 0; // 内部でリトライカウントを管理
  while (retryCount < maxRetries) {
    try {
      // 非同期操作を試行
      const result = await operation();
      return result;
    } catch (error) {
      retryCount++;
      if (retryCount >= maxRetries) {
        throw new Error(`リトライ回数が最大回数(${maxRetries})に達しました: ${error.message}`);
      }
      // 待機時間を指数関数的に増加
      const backoffDelay = delay * Math.pow(2, retryCount - 1);
      console.log(`${backoffDelay}ms待ってリトライします`);
      await new Promise((resolve) => setTimeout(resolve, backoffDelay));
    }
  }
}

// 使用例
const exampleOperation = async () => {
  // 失敗する可能性のある処理を記述
  const randomNumber = Math.random();
  console.log('randomNumber: ', randomNumber);
  if (randomNumber > 0.7) {
    return 'Success';
  } else {
    throw new Error('Failure');
  }
};

exponentialBackoff(5, 1000, exampleOperation)
  .then((result) => console.log(`処理が成功しました: ${result}`))
  .catch((error) => console.error(error.message));

exponentialBackoff関数は、リトライごとに待機時間を2倍に増加させます。これにより、失敗が続く場合にリトライ間隔を長くし、システムへの負担を軽減します。exampleOperationが失敗すると、初回は1秒待機し、次は2秒、4秒と指数関数的に待機時間が増加します。最大5回まで試行します。

あわせて読みたい

エクスポネンシャルバックオフ』については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。

本記事のまとめ

この記事では『JavaScriptでリトライ処理を実装する方法』について、以下の内容を説明しました。

  • リトライ処理とは
  • JavaScriptでリトライ処理を実装する方法
    • エクスポネンシャルバックオフを採用する

お読み頂きありがとうございました。