組み込み関数

JavaScriptのsetTimeout()入門|一定時間後に処理を実行する

setTimeout()は、指定したミリ秒後にコールバック関数を1回だけ実行する組み込み関数です。遅延実行、デバウンス処理、非同期フローの制御など、さまざまな場面で使われます。setInterval()との違いも含めて解説します。

基本的な使い方

setTimeout()は2つの引数を取ります。第1引数は実行するコールバック関数、第2引数は遅延時間(ミリ秒)です。戻り値はタイマーIDで、clearTimeout()でキャンセルに使えます。

JavaScript
// 基本構文
const timerId = setTimeout(コールバック関数, 遅延ミリ秒);

// 2秒後にメッセージを表示
setTimeout(() => {
  console.log("2秒経過しました");
}, 2000);

// 即座に実行される(setTimeout内の処理は後で実行)
console.log("先にこちらが表示されます");

// 引数付きのコールバック
setTimeout((name, greeting) => {
  console.log(`${greeting}, ${name}さん!`);
}, 1000, "田中", "こんにちは");
実行結果
先にこちらが表示されます
// 1秒後:
こんにちは, 田中さん!
// 2秒後:
2秒経過しました

setTimeout()はJavaScriptの非同期処理の基本です。遅延時間が0でも、現在のコードの実行が完了してからコールバックが呼ばれます。

タイマーのキャンセル

clearTimeout()を使うと、まだ実行されていないタイマーをキャンセルできます。ユーザー操作のデバウンスや条件付きキャンセルに必須のパターンです。

JavaScript
// タイマーのキャンセル
const timerId = setTimeout(() => {
  console.log("この処理は実行されません");
}, 3000);

// タイマーをキャンセル
clearTimeout(timerId);
console.log("タイマーをキャンセルしました");

// デバウンス処理の実装
let debounceTimer;
function handleSearch(query) {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => {
    console.log(`検索実行: "${query}"`);
  }, 300);
}

// 高速に入力された場合、最後の入力のみ実行
handleSearch("J");
handleSearch("Ja");
handleSearch("Jav");
handleSearch("Java");
handleSearch("JavaScript"); // この検索のみ実行される
実行結果
タイマーをキャンセルしました
// 300ms後:
検索実行: "JavaScript"

実践的な活用例

setTimeout()はUIのフィードバック表示、自動保存、リトライ処理など実務で多用されます。

JavaScript
// 通知の自動消去
function showNotification(message, duration = 3000) {
  console.log(`通知表示: ${message}`);
  setTimeout(() => {
    console.log(`通知消去: ${message}`);
  }, duration);
}
showNotification("保存しました");

// リトライ処理(指数バックオフ)
function fetchWithRetry(url, retries = 3, delay = 1000) {
  return new Promise((resolve, reject) => {
    function attempt(n) {
      console.log(`試行 ${4 - n}/3 (${delay * Math.pow(2, 3 - n)}ms後)`);
      // fetch(url)の代わりにシミュレーション
      const success = n === 1; // 最後の試行で成功
      if (success) {
        resolve("データ取得成功");
      } else if (n > 0) {
        setTimeout(() => attempt(n - 1), delay * Math.pow(2, 3 - n));
      } else {
        reject("全リトライ失敗");
      }
    }
    attempt(retries);
  });
}

// Promiseベースの遅延関数
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function main() {
  console.log("開始");
  await sleep(1000);
  console.log("1秒後");
  await sleep(1000);
  console.log("2秒後");
}
// main(); // 実行例
実行結果
通知表示: 保存しました
// 3秒後:
通知消去: 保存しました
setInterval()との違い

setTimeout()は1回だけ実行しますが、setInterval()は指定間隔で繰り返し実行します。繰り返し処理が必要な場合はsetInterval()を使いますが、処理時間が長い場合はsetTimeout()の再帰呼び出しの方が安全です。

遅延時間の精度について

setTimeout()の遅延時間は「最低でもこれだけ待つ」という意味であり、正確なタイミングは保証されません。ブラウザのタブが非アクティブだと遅延が大きくなることがあります。また、setTimeout(fn, 0)は即座に実行されるわけではなく、イベントループの次のサイクルで実行されます。

まとめ

  • setTimeout()は指定ミリ秒後にコールバックを1回実行する
  • clearTimeout()でタイマーをキャンセルできる
  • デバウンス処理やリトライ処理に活用できる
  • Promiseと組み合わせてsleep()関数を実装可能
  • 遅延時間は最低保証であり正確なタイミングは保証されない