clearTimeout は「さっき予約した“◯秒後”をなかったことにする」関数
clearTimeout は、setTimeout で予約した「あとで実行する処理」をキャンセルするための関数 です。
「3 秒後に実行して」と予約したけど、その 3 秒の間に状況が変わって
「やっぱり実行しなくていいや」となったときに使います。
アニメーションの中断、
「閉じる前に 5 秒待つ」ダイアログのキャンセル、
入力が続いている間は検索を実行しない(デバウンス)など、
「一度予約した“未来の処理”を取り消す」場面でよく登場します。
clearTimeout を使うための前提:ID をちゃんと持っておく
setTimeout の戻り値が「キャンセル用の鍵」になる
clearTimeout を理解するには、
まず setTimeout が「タイマー ID」を返す ことを押さえる必要があります。
const id = setTimeout(() => {
console.log("3秒後に実行されるはずだった処理");
}, 3000);
JavaScriptこの id が、
「この予約をキャンセルしたいときに必要な鍵」です。
clearTimeout は、この ID を受け取って、
「そのタイマーを無効にする」関数です。
clearTimeout(id);
JavaScriptID をどこに保存するかが設計のポイント
実際のコードでは、
この ID をどこに置いておくかが大事になります。
関数のローカル変数に入れておくのか
モジュールの外側の変数にしておくのか
オブジェクトのプロパティとして持つのか
例えば、ボタンのクリックでタイマーを開始・キャンセルするなら、
外側に変数を用意しておくのが定番です。
let timerId = null;
function start() {
timerId = setTimeout(() => {
console.log("実行!");
}, 3000);
}
function cancel() {
if (timerId !== null) {
clearTimeout(timerId);
timerId = null;
}
}
JavaScript具体例 1:3 秒後に実行される処理をキャンセルする
シンプルな「開始」と「キャンセル」の組み合わせ
HTML をイメージします。
<button id="start">3秒後に実行</button>
<button id="cancel">キャンセル</button>
<div id="log"></div>
JavaScript はこう書けます。
const startButton = document.querySelector("#start");
const cancelButton = document.querySelector("#cancel");
const log = document.querySelector("#log");
let timerId = null;
startButton.addEventListener("click", () => {
if (timerId !== null) {
log.textContent = "すでに予約済みです";
return;
}
log.textContent = "3秒後に実行を予約しました";
timerId = setTimeout(() => {
log.textContent = "処理を実行しました";
timerId = null;
}, 3000);
});
cancelButton.addEventListener("click", () => {
if (timerId !== null) {
clearTimeout(timerId);
timerId = null;
log.textContent = "予約をキャンセルしました";
} else {
log.textContent = "キャンセルする予約はありません";
}
});
JavaScriptここでのポイントは、
「今タイマーが動いているかどうか」を timerId が null かどうかで管理していることです。
予約するたびに timerId に ID を入れる
キャンセルしたら clearTimeout して null に戻す
このパターンは、現場でもそのまま使える基本形です。
具体例 2:「入力が止まってから検索する」デバウンスでの clearTimeout
clearTimeout が本領発揮するパターン
clearTimeout が一番「効いてるな」と感じられるのが、
デバウンス(入力が止まってから処理する) のパターンです。
検索ボックスをイメージします。
<input id="search" placeholder="検索ワードを入力" />
<div id="status"></div>
JavaScript はこう。
const input = document.querySelector("#search");
const status = document.querySelector("#status");
let timerId = null;
input.addEventListener("input", () => {
const keyword = input.value;
if (timerId !== null) {
clearTimeout(timerId); // 前の予約をキャンセル
}
status.textContent = "入力中…";
timerId = setTimeout(() => {
status.textContent = `「${keyword}」で検索します`;
// ここで実際に fetch などで検索 API を叩く
}, 500);
});
JavaScriptここで起きていることを丁寧に言語化すると、
入力があるたびに「500ms 後に検索する」予約を入れる
ただし、その前に「前回の予約」を clearTimeout でキャンセルする
結果として、「最後の入力から 500ms 経ったときだけ検索が走る」
という動きになります。
この「前の予約をキャンセルして、最後のだけ残す」というのが、clearTimeout の一番気持ちいい使い方です。
重要ポイント:clearTimeout は「すでに実行されたもの」は止められない
間に合うのは「まだ実行されていないタイマー」だけ
clearTimeout ができるのは、
「まだ実行されていないタイマーを無効にすること」 だけです。
例えば、こういうコードを考えます。
const id = setTimeout(() => {
console.log("実行!");
}, 1000);
setTimeout(() => {
clearTimeout(id);
console.log("キャンセルしようとした");
}, 2000);
JavaScript1 秒後に「実行!」を出す予約
2 秒後にキャンセルしようとする予約
この場合、1 秒後にはもうコールバックが実行されてしまっているので、
2 秒後に clearTimeout(id) を呼んでも何も起きません。
つまり、
「実行される前にキャンセルする」
というタイミング管理が大事になります。
「もう終わったタイマーの ID」を clearTimeout してもエラーにはならない
clearTimeout に「すでに終わったタイマーの ID」や「null」を渡しても、
エラーにはなりません(ただ何も起きないだけ)。
clearTimeout(null); // 何も起きない
clearTimeout(999999999); // 何も起きない(存在しないID)
JavaScriptなので、実務では
「とりあえず clearTimeout(timerId) してから、新しいタイマーをセットする」
という書き方がよく使われます。
clearTimeout(timerId);
timerId = setTimeout(...);
JavaScriptこれで、「前の予約が残っていても消す」「なくても問題ない」という安全な書き方になります。
setTimeout と clearTimeout をセットで設計する感覚
「予約」と「キャンセル」は常にペアで考える
setTimeout を使うときは、
「この予約をキャンセルしたくなる状況はあるか?」
を一緒に考えるクセをつけると、設計が一段うまくなります。
アニメーションの終了を遅らせる
→ ユーザーが途中で画面を閉じたら?
自動で閉じる通知を 5 秒後に消す
→ ユーザーが自分で閉じたら?
入力が止まってから検索する
→ まだ入力が続いているのに前の予約が残っていたら?
こういう「途中で状況が変わる」ケースを想像すると、
自然と clearTimeout の出番が見えてきます。
「状態」と一緒に管理するのがコツ
タイマー ID は、
「今どんな状態か」を表す一部として扱うと分かりやすいです。
タイマーが動いている → timerId に数値が入っている
タイマーが止まっている → timerId が null
というふうに、「状態」として変数を扱うと、
二重にタイマーを起動しない
止めるべきときにちゃんと止める
といった制御がしやすくなります。
初心者として clearTimeout で本当に掴んでほしいこと
clearTimeout は「setTimeout で予約した処理をキャンセルする」ための関数
キャンセルするには、setTimeout の戻り値(タイマー ID)をちゃんと保存しておく必要がある
「前の予約をキャンセルして、最後のだけ残す」デバウンスのようなパターンで真価を発揮する
実行されてしまったタイマーは止められないので、「いつキャンセルするか」のタイミング設計が重要clearTimeout に「終わった ID」や null を渡してもエラーにはならないので、まず消してから新しく予約する書き方がよく使われる
小さな練習として、
3 秒後に色が変わるボックス
→ その前にマウスを乗せたら clearTimeout でキャンセルする
みたいな UI を作ってみると、
「予約した未来をなかったことにする感覚」が、手触りとして掴めるはずです。
