3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるsetTimeout / setIntervalの設計的注意点と非同期との統合戦略

Posted at

概要

setTimeoutsetInterval は「遅らせて処理する」ための単純なAPIではない。
それは**“非同期制御・イベントループ・状態変化のタイミングを制御するための、明示的な設計手段”**である。

タイマー系関数は軽視されやすいが、使用の文脈と設計意図が不明確なまま導入されると、メモリリーク・タイミング競合・予期せぬ再発火など、重大な設計不良を引き起こす。

本稿では、setTimeout / setIntervalの設計的運用と、async/awaitやPromiseとの統合的な使い方を解説する。


1. setTimeout の基本構造と設計目的

setTimeout(() => {
  console.log("300ms後に実行");
}, 300);
  • 一度だけ実行される遅延処理
  • ✅ アニメーション・非同期連携の待機処理・バックオフ処理に使用

2. setInterval の危険性と設計上の罠

setInterval(() => {
  updateStatus();
}, 1000);
  • 処理が1秒以上かかると積み上がる(前回の処理中に次の実行が走る)
  • ✅ 長期的な監視や更新には setTimeout を再帰的に使う方が安全
function loop() {
  updateStatus();
  setTimeout(loop, 1000);
}
loop(); // ✅ 安定した間隔

3. タイマーをPromise化して非同期と統合する

function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function runWithDelay() {
  await wait(500);
  console.log("500ms後に実行");
}
  • async/await明示的な非同期制御に組み込める
  • ✅ テストや処理順制御にも有効

4. setTimeoutは「最低保証時間」であって正確なスケジューラではない

setTimeout(() => {
  console.log("Expected ~100ms"); // 実際は遅れる可能性あり
}, 100);
  • ❌ イベントループや他の処理が重いと遅延が保証されない
  • ✅ 正確な間隔が必要ならDate.now() を使って自力で時間制御
const start = Date.now();
setTimeout(() => {
  console.log(Date.now() - start); // 実測との差分確認
}, 100);

5. 明示的にクリアしなければリークや重複が発生する

const id = setTimeout(doSomething, 1000);
clearTimeout(id); // ✅ 明示的に停止可能

const loopId = setInterval(pollData, 2000);
clearInterval(loopId); // ✅ イベント終了時などにクリア必須
  • clearTimeout / clearIntervalライフサイクルとセットで設計する

設計判断フロー

① 単発の遅延実行か、周期的な監視処理か?

② setIntervalの実行間隔は、処理時間を超えていないか?

③ タイマーのIDは保持・キャンセルできるよう設計されているか?

④ async/awaitと組み合わせる場合、Promise化されたwait関数を使っているか?

⑤ ライフサイクルの終了時にclearTimeout / clearIntervalを忘れていないか?

よくあるミスと対策

❌ setIntervalの中の処理が重く、ループが破綻

→ ✅ 再帰的setTimeout構造で実行間隔を安定化


❌ タイマーを止める手段がないまま放置され、リーク発生

→ ✅ return用のclearTimeout関数 or フラグによる明示的制御


❌ async関数の中でsetTimeoutを使いたいが await できない

→ ✅ Promise化された wait(ms) ヘルパー関数を導入


結語

setTimeout / setIntervalとは「遅延処理のための低級API」ではない。
それは**“処理タイミング・イベントライフサイクル・非同期フローを構造的に制御するための設計ツール”**である。

  • setTimeout は再帰で使えば安全なタイミング制御が可能
  • setInterval は積み上がりの危険性を常に伴う
  • async/awaitとの組み合わせには Promise化 という戦略が必要

JavaScriptにおけるタイマー制御とは、
“非同期の秩序と構造を保証するための、明示的・戦略的な制御設計”である。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?