🎎

setIntervalのリスクと再帰的なsetTimeoutへの書き換え方

2023/02/23に公開

とある社内プロジェクト、再起的に処理を実行したかったので安易にsetIntervalメソッドを使って実装しました。

社内レビューに出したところ「setIntervalは指定した時間内に処理を完了できなかったら、処理が途中で終わるリスクがある」とのご指摘をいただきました。

この記事では、setIntervalのリスクとそのリスクを回避するための代替案を記事にしました。

setIntervalのリスク

例えば以下のようなコードがあるとします。

function myFunction() {
  // 100msより長い時間実行される処理
}

setInterval(myFunction, 100);

この時、100msを超えた時点で前のmyFunctionの処理と次のmyFunctionの処理が重なってしまい、前のmyFunctionの処理が正常に完了しないリスクがあるとのことでした。

再帰的なsetTimeoutへの書き換え

setIntervalの代わりに、再帰的なsetTimeoutへ書き換えができます。
これにより、前回の関数実行が完了する前に次の関数実行が発生する可能性が低くなります。

以下は、再帰的なsetTimeoutを使用してsetIntervalを置き換える例です。

function myFunction() {
  // 100msより長い時間実行される処理
  
  setTimeout(myFunction, 100);
}

// 最初の関数実行をトリガーするために、最初のsetTimeoutを呼び出します。
setTimeout(myFunction, 100);

このように実装することで、myFunctionの処理が完了する前に次のsetTimeoutが発生することはありません。

参考

https://ja.javascript.info/settimeout-setinterval#ref-618

Discussion