[JavaScript] setTimeout과 setInterval

호출 스케줄링

setTimeout(func, delay, ...args)

지정된 delay(밀리초) 후에 func 함수를 한 번 실행합니다.

반환되는 값은 타이머 식별자(timer ID)로, 이를 이용해 clearTimeout으로 예약된 호출을 취소할 수 있습니다.

setInterval(func, delay, ...args)

지정된 delay 간격마다 func 함수를 반복적으로 실행합니다.

이 역시 타이머 식별자를 반환하며, clearInterval로 반복 실행을 중단할 수 있습니다.

setTimeout

간단한 지연 실행

function showMessage() {
  console.log("2초 후에 이 메시지가 표시됩니다.");
}

// 2000ms(2초) 후에 showMessage 함수를 한 번 실행합니다.
const timeoutId = setTimeout(showMessage, 2000);

매개변수 전달

function greet(user, message) {
  console.log(`${user}님, ${message}`);
}

// 1초 후에 greet 함수를 실행하면서 매개변수를 전달합니다.
setTimeout(greet, 1000, "홍길동", "안녕하세요!");

호출 취소

function task() {
  console.log("이 함수는 실행되지 않습니다.");
}

const timerId = setTimeout(task, 3000);

// 타이머를 취소하여 task 함수의 실행을 방지합니다.
clearTimeout(timerId);

중첩 setTimeout을 이용한 반복 실행

setTimeout을 재귀적으로 호출하여 일정한 간격으로 함수를 반복 실행할 수 있습니다. 이 방식은 각 실행 간의 간격을 동적으로 조절할 수 있어 setInterval보다 유연합니다.

let delay = 1000;

function dynamicRepeat() {
  console.log(`다음 실행까지 ${delay}ms 남았습니다.`);

  // 실행 후 조건에 따라 지연 시간 변경
  delay += 500;

  setTimeout(dynamicRepeat, delay);
}

setTimeout(dynamicRepeat, delay);

setInterval

주기적인 작업 실행

function updateClock() {
  const now = new Date();
  console.log(`현재 시간: ${now.toLocaleTimeString()}`);
}

// 1초마다 현재 시간을 출력합니다.
const intervalId = setInterval(updateClock, 1000);

반복 실행 중단

let count = 0;

function limitedRepeat() {
  count += 1;
  console.log(`반복 횟수: ${count}`);

  if (count >= 5) {
    clearInterval(intervalId);
    console.log("반복이 중단되었습니다.");
  }
}

const intervalId = setInterval(limitedRepeat, 1000);

실행 지연

함수가 실행되는 데 시간이 오래 걸리면, 다음 실행이 예상 시간보다 지연될 수 있습니다.

function longTask() {
  const start = Date.now();

  // 1500ms 동안 실행되는 작업 시뮬레이션
  while (Date.now() - start < 1500) {}

  console.log("긴 작업 완료");
}

// 1000ms(1초)마다 longTask를 실행
setInterval(longTask, 1000);

대기 시간이 0인 setTimeout

대기 시간을 0으로 설정하면, 현재 실행 중인 스크립트가 완료된 후 가능한 한 빨리 지정한 함수가 실행됩니다.

console.log("첫 번째 로그");

setTimeout(() => {
  console.log("세 번째 로그 - 대기 시간 0");
}, 0);

console.log("두 번째 로그");

주의사항

  • 정확한 간격 보장 어려움: setInterval은 지정한 간격대로 실행을 보장하지 않으므로, 정확한 타이밍이 필요한 경우 setTimeout의 재귀 호출 방식을 사용하는 것이 좋습니다.
  • 최소 지연 시간 적용: HTML 표준에 따라 연속해서 중첩된 타이머의 최소 지연 시간은 4ms입니다. 이는 타이머 스로틀링이라고도 하며, 타이머의 효율적인 사용을 보장합니다.

정확한 간격을 위한 setTimeout 재귀 호출

function preciseTask() {
  const start = Date.now();

  // 작업 내용
  console.log("정확한 간격으로 실행되는 작업");

  // 작업 소요 시간 측정
  const duration = Date.now() - start;

  // 다음 실행 스케줄링 (지연 시간에서 작업 시간을 빼줌)
  setTimeout(preciseTask, 1000 - duration);
}

setTimeout(preciseTask, 1000);