JavaScript 逆引き集 | 取消可能タイマー(clearTimeout)

JavaScript JavaScript
スポンサーリンク

取消可能タイマーの基本 — const id = setTimeout(...); clearTimeout(id)

「一定時間後に一度だけ実行」するのが setTimeout。その実行予約はタイマーIDで管理でき、必要なくなったら clearTimeout(id) で取り消せます。UIやページ遷移時の後処理、誤タップ対策などで必須の基礎テクです。


基本の使い方

// 3秒後にメッセージ表示を予約
const id = setTimeout(() => {
  console.log("3秒経過");
}, 3000);

// 予約を取り消す
clearTimeout(id);
JavaScript
  • タイマーID: setTimeout の戻り値。これを保存しておけば後でキャンセル可能。
  • 取り消しの瞬間: 指定時間「前」に clearTimeout(id) が呼ばれれば、コールバックは実行されない。

よく使うテンプレート集

遅延表示のキャンセル(ユーザー操作で止める)

let tid = null;

function scheduleHint() {
  tid = setTimeout(() => showHint("ここをクリック"), 2000);
}

function cancelHint() {
  if (tid) clearTimeout(tid);
}

// 例: 入力が始まったらヒントを出さない
input.addEventListener("focus", cancelHint);
JavaScript
  • ラベル: 直前に「出す予定」にしていても、操作が入れば取り消す。

ページ遷移やクリーンアップ時に止める

let tid = setTimeout(fetchAndRender, 5000);

// SPAの画面から離れる直前
function onLeavePage() {
  clearTimeout(tid);  // 古い画面用の処理が走らないように
}
JavaScript
  • ラベル: 古い画面に紐づく処理は撤収。副作用の暴発を防ぐ。

ボタンで開始・停止(初心者向け鉄板)

let tid = null;

startBtn.onclick = () => {
  tid = setTimeout(() => alert("5秒経過"), 5000);
};

stopBtn.onclick = () => {
  if (tid) clearTimeout(tid);
};
JavaScript
  • ラベル: IDをスコープに保持し、いつでも clearTimeout

再帰的な setTimeout の安全停止

let tid = null;
let count = 0;

function tick() {
  console.log("tick", ++count);
  if (count < 5) tid = setTimeout(tick, 1000);
}

tid = setTimeout(tick, 1000);

// 途中でやめたい場合
stopBtn.onclick = () => clearTimeout(tid);
JavaScript
  • ラベル: 次回予約のIDを更新しておけば、最新の予約を止められる。

実務でのパターンとコツ

  • ラベル:IDの管理場所
    • ポイント: コンポーネントやクラスのフィールド(またはクロージャ変数)に保持。複数あるなら配列に入れて一括停止。
  • ラベル:ダブル予約防止
    • ポイント: 新規予約前に clearTimeout(tid) を呼んでから再設定する(重複実行を避ける)。
if (tid) clearTimeout(tid);
tid = setTimeout(run, 1000);
JavaScript
  • ラベル:非同期と組み合わせる
    • ポイント: タイムアウトの実装は Promise.race でも可能だが、UIの簡易遅延や演出には setTimeoutclearTimeout が手軽。
  • ラベル:メモリ・副作用対策
    • ポイント: 画面破棄・Unmount・イベント解除時に必ず clearTimeout。予期せぬ実行で古いDOMを触るバグを防ぐ。

ありがちなハマりポイントと対策

  • ラベル:タイマーIDを取り違える
    • 症状: 別のIDを止めようとしてキャンセルできない。
    • 対策: 予約直後に必ず保存。複数IDは名前を付ける(例:hintTid, fetchTid)。
  • ラベル:予約の上書き忘れ
    • 症状: 連打でタイマーが複数生まれ、同じ処理が何度も走る。
    • 対策: 新規予約前に必ず clearTimeout してから再予約。
  • ラベル:スコープから消える
    • 症状: const id がローカルにあって外から止められない。
    • 対策: 停止が必要な範囲でIDを共有(フィールドや外側スコープ)。
  • ラベル:ミリ秒単位の勘違い
    • 症状: 1秒を 1 と書いて何も起きない。
    • 対策: 1000ms = 1秒。人間の秒をミリ秒に直す癖をつける。

練習問題(手を動かして覚える)

// 1) 3秒後の実行を1秒後にキャンセル
const id1 = setTimeout(() => console.log("実行される?"), 3000);
setTimeout(() => clearTimeout(id1), 1000);

// 2) 連打でも常に最新だけが有効(前回はキャンセル)
let tid2 = null;
function scheduleOnce() {
  if (tid2) clearTimeout(tid2);
  tid2 = setTimeout(() => console.log("最新の予約が実行"), 1000);
}
scheduleOnce(); scheduleOnce(); scheduleOnce(); // 最後の1回のみ

// 3) 再帰的setTimeoutを3回で停止
let tid3 = null, n = 0;
function repeat3() {
  console.log("tick", ++n);
  if (n < 3) tid3 = setTimeout(repeat3, 500);
}
tid3 = setTimeout(repeat3, 500);

// 4) ボタンクリックで開始→もう一度クリックで停止(トグル)
let tid4 = null;
function toggleTimer() {
  if (tid4) { clearTimeout(tid4); tid4 = null; console.log("停止"); }
  else { tid4 = setTimeout(() => { console.log("実行"); tid4 = null; }, 2000); }
}
JavaScript

直感的な指針

  • 予約したらIDを持つ。止めたいときは clearTimeout(id)
  • 新規予約前に前回をキャンセルして「最新だけ」を生かす。
  • 画面破棄・遷移・ユーザー操作で不要になったら、確実に止める。

タイトルとURLをコピーしました