JavaScript | Web API:タイマー・スケジューリング - setInterval

JavaScript JavaScript
スポンサーリンク

setInterval は「◯秒ごとにこれを繰り返して」と予約する関数

setTimeout が「一回だけあとで実行」だとしたら、
setInterval「一定間隔で同じ処理を何度も繰り返す」 ためのタイマー関数です。

1 秒ごとに時計を更新したい
5 秒ごとにサーバーに状態を取りに行きたい
0.1 秒ごとにアニメーションのフレームを進めたい

みたいな「定期的に同じことをしたい」場面で使います。

ポイントは、「止めない限りずっと続く」 ということです。
なので、「どう始めるか」と同じくらい「どう止めるか」が重要になります。


setInterval の基本形と実行タイミング

一番シンプルな書き方

基本形はこれです。

setInterval(実行したい関数, 間隔ミリ秒);
JavaScript

例えば、1 秒ごとにメッセージを出したいならこう。

setInterval(() => {
  console.log("1秒経ちました");
}, 1000);
JavaScript

これで、

1 秒後に 1 回目
さらに 1 秒後に 2 回目
さらに 1 秒後に 3 回目…

というふうに、同じ処理が延々と繰り返されます。

「最初の 1 回目」も待つことに注意

setInterval は、呼び出した瞬間に実行されるわけではありません。

console.log("A");

setInterval(() => {
  console.log("B");
}, 1000);

console.log("C");
JavaScript

この場合の出力はこうです。

A
C
(1秒後)B
(さらに1秒後)B
…

つまり、

setInterval を呼ぶ
→ すぐには実行されない
→ 指定した時間が経つたびに実行される

という流れです。

「最初の 1 回だけすぐ実行して、その後は一定間隔で繰り返したい」場合は、
最初の 1 回を自分で呼んでから setInterval を設定する、という書き方をします。

function tick() {
  console.log("tick");
}

tick(); // 最初の1回をすぐ実行
setInterval(tick, 1000); // その後は1秒ごとに実行
JavaScript

setInterval を止める:clearInterval

ID を受け取って、あとから止められる

setIntervalsetTimeout と同じく、呼び出したときに「タイマー ID」を返します。

const id = setInterval(() => {
  console.log("繰り返し実行中");
}, 1000);
JavaScript

この idclearInterval に渡すことで、
「もう繰り返さなくていいよ」と止めることができます。

clearInterval(id);
JavaScript

例えば、「スタートボタンで開始して、ストップボタンで止める」簡単なタイマー。

const startButton = document.querySelector("#start");
const stopButton = document.querySelector("#stop");
const display = document.querySelector("#display");

let count = 0;
let timerId = null;

startButton.addEventListener("click", () => {
  if (timerId !== null) return; // 二重起動防止

  timerId = setInterval(() => {
    count++;
    display.textContent = `${count} 秒経過`;
  }, 1000);
});

stopButton.addEventListener("click", () => {
  if (timerId !== null) {
    clearInterval(timerId);
    timerId = null;
  }
});
JavaScript

ここでのポイントは、

タイマー ID を変数に保存しておく
止めたら null に戻して「今は動いていない」状態を表す

という管理の仕方です。


setInterval と「処理時間」の関係で知っておくべきこと

間隔は「最低でもこのくらい空けたい」という目安

setInterval に指定した時間は、
「この間隔より短くはならない」 という目安です。

例えば、こう書いたとします。

setInterval(() => {
  console.log("重い処理開始");
  const start = Date.now();
  while (Date.now() - start < 1500) {
    // 1.5秒かかる重い処理
  }
  console.log("重い処理終了");
}, 1000);
JavaScript

「1 秒ごとに実行してほしい」と書いていますが、
中の処理が 1.5 秒かかっているので、実際には

1 回目の処理に 1.5 秒
終わってから「次の 1 秒待ち」が始まる

という感じになり、
実行間隔は 2.5 秒くらいになります。

つまり、

処理が長引くと、実際の間隔は伸びる
「指定した間隔きっちり」にはならない

ということです。

「正確なタイマー」が必要なときは、
Date.now() などで時間を測りながら調整する必要があります。

setInterval より「setTimeout の再帰」のほうが好まれる場面

実務では、
setInterval よりも「setTimeout を繰り返し呼ぶ」書き方が好まれることも多いです。

function tick() {
  console.log("tick");
  setTimeout(tick, 1000);
}

tick();
JavaScript

この書き方だと、

処理が終わってから 1 秒待つ
→ 実行
→ 終わってから 1 秒待つ

という流れになるので、
「処理時間も含めて一定のリズムで動かしたい」場合に向いています。

setInterval は「処理が重くなったときに、次の実行が詰まってくる」ことがあるので、
「1 回終わってから次の予約をする」というスタイルのほうが安全なことも多いです。


実用例 1:現在時刻を 1 秒ごとに表示する時計

HTML 側

<div id="clock"></div>

JavaScript 側

const clock = document.querySelector("#clock");

function updateClock() {
  const now = new Date();
  const h = String(now.getHours()).padStart(2, "0");
  const m = String(now.getMinutes()).padStart(2, "0");
  const s = String(now.getSeconds()).padStart(2, "0");
  clock.textContent = `${h}:${m}:${s}`;
}

updateClock(); // 最初の1回をすぐ実行
setInterval(updateClock, 1000); // その後は1秒ごとに更新
JavaScript

ここでやっていることは、

現在時刻を文字列にして表示する関数 updateClock を作る
最初に一度だけすぐ実行して表示を作る
その後は 1 秒ごとに updateClock を呼ぶ

というシンプルなパターンです。

「setInterval で UI を定期更新する」という典型的な使い方です。


実用例 2:一定時間ごとにサーバーに状態を取りに行く(ポーリング)

シンプルなポーリングの例

リアルタイム性がそこまでシビアでない場合、
WebSocket ではなく「数秒ごとに API を叩く」という方法がよく使われます。

async function fetchStatus() {
  try {
    const res = await fetch("/api/status");
    if (!res.ok) throw new Error("HTTP error");
    const data = await res.json();
    console.log("現在のステータス:", data);
  } catch (e) {
    console.error("ステータス取得に失敗しました", e);
  }
}

fetchStatus(); // 最初の1回
const id = setInterval(fetchStatus, 5000); // 5秒ごとに実行
JavaScript

これで、

最初に一度だけ状態を取得
その後は 5 秒ごとに最新状態を取りに行く

という動きになります。

ただし、
「ページを離れたのにまだポーリングし続けている」
みたいなことにならないように、
必要がなくなったら clearInterval で止める設計が大事です。


初心者として setInterval で本当に掴んでほしいこと

setInterval は「一定間隔で同じ処理を繰り返す」ためのタイマー
止めない限り永遠に続くので、clearInterval で止める設計が必須
最初の 1 回目も待つので、「すぐ実行したいときは自分で一度呼んでから setInterval」
処理が重いと、指定した間隔どおりにはならない(実際の間隔は伸びる)
場合によっては「setTimeout を繰り返す」スタイルのほうが安全で扱いやすい

まずは、

1 秒ごとに数字をカウントアップする
1 秒ごとに背景色を変える
時計を作ってみる

みたいな小さな遊びから始めてみてください。

「時間の流れに合わせて UI が動く」感覚を一度掴むと、
アニメーション、ポーリング、カウントダウンなど、
「時間を味方につけたコード」 を書くのが一気に楽しくなります。

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