【JavaScript入門】指定時間後の処理

 ゲームのカウントダウン、通知のスヌーズ、アニメーションのフレーム更新――「○秒後に 1 回だけ」「一定間隔で何度も」というタイミング制御はフロントエンド開発で欠かせません。ブラウザ JavaScript には setTimeoutsetInterval の 2 つのタイマー API があり、対応する clearTimeout / clearInterval で停止できます。本章では API の違いと使い分けを整理し、実動サンプルで ID の扱い方やキャンセル方法を体験します。

1.タイマー API 一覧

メソッド戻り値主な用途備考
setTimeout(fn, ms = 0)timerIDms 後に 1 回だけ fn 実行0 でも最短 4 ms 程度
clearTimeout(id)なしsetTimeout を中止有効 ID でなければ無視
setInterval(fn, ms)intervalIDms 間隔で繰り返し fn 実行実質最小 ~10 ms
clearInterval(id)なしsetInterval を中止有効 ID でなければ無視

 共通ポイント

  • どちらも 非同期: コールバックはイベントループのタスクキューに積まれる。
  • 返ってくる ID は 数値(Node.js ではオブジェクト)
  • ブラウザタブが非アクティブになると最小間隔が延びる場合がある。

2.実践サンプル ― 5 秒カウントダウン & 自動停止

ファイル名: timer_demo.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>指定時間後の処理デモ</title>
<style>
body{font-family:sans-serif;margin:2rem}
#time{font-size:2rem;margin:.5rem 0}
button{padding:.4rem .8rem;margin-right:.5rem}
</style>
</head>
<body>
<h2>⏱️ 5 秒後にメッセージを表示</h2>
<p id="time">待機中…</p>
<button id="start">スタート</button>
<button id="cancel" disabled>キャンセル</button>

<script>
(() => {
  let timerID   = null; // setTimeout 用
  let intervalID = null; // setInterval 用
  const MAX = 5;        // 秒数
  const display = document.getElementById('time');
  const btnStart = document.getElementById('start');
  const btnCancel = document.getElementById('cancel');

  btnStart.onclick = () => {
    if (timerID) return;            // 二重起動防止
    let rest = MAX;
    display.textContent = `${rest} 秒後に実行します`;
    btnCancel.disabled = false;

    // 1 秒ごとに残り時間を更新
    intervalID = setInterval(() => {
      rest--;
      display.textContent = `${rest} 秒後に実行します`;
    }, 1000);

    // 5 秒後に 1 回だけ実行
    timerID = setTimeout(() => {
      clearInterval(intervalID);
      display.textContent = '💥 タイムアップ!処理を実行しました';
      btnCancel.disabled = true;
      timerID = intervalID = null;
    }, MAX * 1000);
  };

  btnCancel.onclick = () => {
    clearTimeout(timerID);
    clearInterval(intervalID);
    display.textContent = '⏹️ キャンセルしました';
    btnCancel.disabled = true;
    timerID = intervalID = null;
  };
})();
</script>
</body>
</html>

ブラウザ挙動

  1. [スタート] を押すと「5 秒後に実行します」と表示され、1 秒ごとに 4 → 3 → … とカウントダウン。
  2. 0 秒になると setTimeout が発火し「💥 タイムアップ!」を表示。
  3. 途中で [キャンセル] を押すと clearTimeoutclearInterval が走り、カウントもメッセージも停止。

プログラム解説

処理説明
setInterval残り秒数を 1000 ms 間隔で更新。ID を intervalID に保持
setTimeout5000 ms 後に本処理。ID を timerID に保持
clearInterval(intervalID)タイムアップ時・キャンセル時にカウントダウン停止
clearTimeout(timerID)キャンセル時に 1 回限りの実行を取り消し。
ガード節既に timerID が存在すれば二重起動を防ぐ。

3.setTimeout でループを書くパターン

function loop(){
  // 処理…
  setTimeout(loop, 16); // 約 60fps
}
loop();
  • フレームずれを自己補正できる
  • setInterval より描画タイミングのブレが少ない

4.Promise / async await との併用

const sleep = ms => new Promise(r => setTimeout(r, ms));
await sleep(2000); // 2 秒待機して次の処理

非同期関数内で「待ち」を直感的に書けるため、近年はこちらが主流です。

まとめ

  • 1 回だけsetTimeout / 繰り返しsetInterval
  • 返却 ID を保持し 必ず clearXxx で停止 するクセを付ける。
  • 高度なアニメーションは requestAnimationFrame、ロジック待機は await sleep() と使い分けると実装がスッキリします。