setInterval は一定の時間間隔で関数を繰り返し実行するためのタイマー関数です。カウントダウンタイマー、リアルタイム時計、自動スライドショー、API のポーリングなど、定期実行が必要な場面で幅広く使われます。
・setInterval の基本構文と戻り値
・clearInterval でタイマーを停止する方法
・実行回数を制限する方法
・setTimeout の再帰呼び出しとの違い
・バックグラウンドタブでの挙動
・メモリリーク防止のクリーンアップ
・カウントダウン・時計・スライドショー・ポーリングの実務パターン
setInterval の基本構文
const intervalId = setInterval(callback, delay, arg1, arg2, ...); // callback: 繰り返し実行する関数 // delay: 実行間隔(ミリ秒)。1000 = 1秒 // arg1...: callback に渡す引数(省略可) // 戻り値: タイマーID(clearInterval で停止に使う)
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log(count);
}, 1000);
// 出力: 1, 2, 3, 4, 5, ...(1秒ごと)
0 を指定しても即座には実行されません。ブラウザは最低約 4ms の間隔を保証します。また、最初の実行は delay ミリ秒後です(即座ではありません)。clearInterval でタイマーを停止する
setInterval は clearInterval で明示的に停止するまで永久に繰り返されます。不要になったタイマーは必ず停止しましょう。
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log(count);
// 5回実行したら停止
if (count >= 5) {
clearInterval(intervalId);
console.log("停止しました");
}
}, 1000);
// 出力: 1, 2, 3, 4, 5, "停止しました"
ボタンで開始・停止を制御する
let intervalId = null;
document.getElementById("startBtn").addEventListener("click", () => {
// 二重起動を防止
if (intervalId !== null) return;
intervalId = setInterval(() => {
console.log("実行中:", new Date().toLocaleTimeString());
}, 1000);
});
document.getElementById("stopBtn").addEventListener("click", () => {
clearInterval(intervalId);
intervalId = null;
});
intervalId !== null のチェックで二重起動を防止してください。setInterval と setTimeout の再帰呼び出しの違い
定期実行には setInterval のほかに、setTimeout を再帰的に呼び出す方法もあります。両者の違いを理解することが重要です。
// 1秒間隔で実行(処理時間が長いと次の実行が詰まる可能性あり)
setInterval(() => {
heavyProcess(); // 処理に300msかかる場合
}, 1000);
// 実際の間隔: 1000ms → 次の実行開始は700ms後
function repeat() {
heavyProcess(); // 処理に300msかかる場合
setTimeout(repeat, 1000);
}
repeat();
// 実際の間隔: 処理300ms + 待機1000ms = 1300ms
| 比較項目 | setInterval | setTimeout 再帰 |
|---|---|---|
| 間隔のカウント | 前回の開始から次の開始まで | 前回の完了から次の開始まで |
| 処理が遅い場合 | 実行が積み重なる可能性あり | 確実に前の処理が完了してから次を実行 |
| 非同期処理 | 完了を待たずに次が実行される | async/await と組み合わせ可能 |
| コードの簡潔さ | シンプル | やや冗長 |
setInterval、重い処理や非同期処理(API 呼び出し)には setTimeout 再帰が安全です。async/await と setTimeout 再帰の組み合わせ
async function pollApi() {
try {
const res = await fetch("/api/status");
const data = await res.json();
console.log("ステータス:", data.status);
if (data.status !== "complete") {
// 処理完了後に5秒後に再実行
setTimeout(pollApi, 5000);
}
} catch (error) {
console.error("エラー:", error);
// エラー時も再試行
setTimeout(pollApi, 10000);
}
}
pollApi();
バックグラウンドタブでの挙動
ブラウザはバッテリーや CPU の消費を抑えるため、バックグラウンドタブでは setInterval の実行間隔を最低 1000ms に制限します(Chrome・Firefox・Safari 共通)。
| 状態 | 指定 100ms の場合 | 指定 2000ms の場合 |
|---|---|---|
| フォアグラウンド | 100ms 間隔で実行 | 2000ms 間隔で実行 |
| バックグラウンド | 1000ms に引き伸ばされる | 2000ms のまま |
Date.now() で経過時間を計算するようにしましょう。バックグラウンドタブに切り替えてもタイマーがずれなくなります。メモリリーク防止(クリーンアップ)
clearInterval を呼ばずにページ遷移やコンポーネント破棄が行われると、タイマーが残り続けてメモリリークの原因になります。
SPA(React)でのクリーンアップ
import { useEffect, useState } from "react";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setCount(prev => prev + 1);
}, 1000);
// クリーンアップ: コンポーネント破棄時に停止
return () => clearInterval(id);
}, []);
return <p>{count}秒経過</p>;
}
イベントリスナーの解除とセット
// ページを離れるときにタイマーを停止
let intervalId = setInterval(doSomething, 1000);
window.addEventListener("beforeunload", () => {
clearInterval(intervalId);
});
実務でよく使うパターン
カウントダウンタイマー
function countdown(seconds, onTick, onComplete) {
let remaining = seconds;
onTick(remaining);
const id = setInterval(() => {
remaining--;
onTick(remaining);
if (remaining <= 0) {
clearInterval(id);
onComplete();
}
}, 1000);
return id; // 外部から停止可能
}
// 使用例: 10秒カウントダウン
countdown(
10,
(sec) => console.log(`残り${sec}秒`),
() => console.log("タイムアップ!")
);
リアルタイム時計
function startClock(elementId) {
const el = document.getElementById(elementId);
function update() {
el.textContent = new Date().toLocaleTimeString("ja-JP");
}
update(); // 初回即時表示
return setInterval(update, 1000);
}
const clockId = startClock("clock");
// 停止: clearInterval(clockId);
自動スライドショー
const slides = document.querySelectorAll(".slide");
let current = 0;
function showSlide(index) {
slides.forEach(s => s.classList.remove("active"));
slides[index].classList.add("active");
}
// 3秒ごとに次のスライドに切り替え
const slideInterval = setInterval(() => {
current = (current + 1) % slides.length;
showSlide(current);
}, 3000);
// マウスホバーで一時停止
const container = document.querySelector(".slideshow");
container.addEventListener("mouseenter", () => clearInterval(slideInterval));
API ポーリング(setTimeout 再帰版)
let isPolling = true;
async function pollNotifications() {
if (!isPolling) return;
try {
const res = await fetch("/api/notifications");
const data = await res.json();
if (data.length > 0) {
renderNotifications(data);
}
} catch (e) {
console.error("通知取得エラー:", e);
}
// 30秒後に再実行
setTimeout(pollNotifications, 30000);
}
pollNotifications();
// 停止: isPolling = false;
関連記事
- setTimeout による遅延実行の方法
- カウントダウンタイマーの作成
- アコーディオンの作り方 — CSS アニメーション
- スムーススクロールを実装する方法
- 日付を取得する方法 — Date オブジェクト
よくある質問
update(); const id = setInterval(update, 1000);setInterval(コードがシンプル)。API 呼び出しなど重い処理や非同期処理には setTimeout 再帰(前の処理完了を待ってから次を実行)が安全です。Date.now() で経過時間を計算するようにしましょう。setCount(prev => prev + 1) のように関数形式の更新を使えば、常に最新の値に基づいて更新されます。クリーンアップ関数で clearInterval を忘れないようにしましょう。まとめ
setInterval は一定間隔で処理を繰り返し実行するための基本的なタイマー関数です。
- 基本:
setInterval(fn, delay)で delay ミリ秒ごとに fn を実行 - 停止:
clearInterval(id)で明示的に停止(必須) - setTimeout との違い: setInterval は開始基準、setTimeout 再帰は完了基準の間隔
- バックグラウンド: 最低 1000ms に制限される。正確な時間は Date.now() で計算
- クリーンアップ: コンポーネント破棄時やページ離脱時に必ず clearInterval する
カウントダウン、時計、スライドショーなどの定期実行には setInterval が最適です。API ポーリングなど非同期処理の定期実行には setTimeout 再帰を使い分けてください。