JavaScript 호출 스케줄링 정리
호출 스케줄링은 특정 시간이 지난 후에 함수를 실행하도록 예약하는 것을 의미합니다.
JavaScript에서는 대표적으로 두 가지 방법을 제공합니다.
setTimeout: 일정 시간 후 한 번 실행setInterval: 일정 시간마다 반복 실행
1. setTimeout
setTimeout은 지정된 시간이 지난 후 함수를 한 번만 실행합니다.
첫 번째 인자: 실행할 함수
두 번째 인자: 지연 시간(ms)
기본 사용법
// 3초 후에 메시지 출력
setTimeout(() => {
console.log('3초가 지남');
}, 3000);
타이머 취소하기
clearTimeout을 사용하면 예약된 함수가 실행되기 전에 취소할 수 있습니다.
const timer = setTimeout(() => {
console.log('이 메시지는 출력되지 않음');
}, 5000);
// 타이머 취소
clearTimeout(timer);
실용 예제: 디바운싱
사용자가 입력을 멈춘 후 0.5초 뒤에 검색을 실행하는 예제입니다.
let searchTimer;
function handleSearch(keyword) {
clearTimeout(searchTimer);
searchTimer = setTimeout(() => {
console.log(`검색 실행: ${keyword}`);
// API 호출 등의 검색 로직
}, 500);
}
handleSearch('버블');
handleSearch('버블콘'); // 이것만 500ms 후 실행됨
2. setInterval
setInterval은 일정한 시간 간격마다 함수를 반복해서 실행합니다.
clearInterval로 중단하기 전까지 계속 실행됩니다.
기본 사용법
let count = 0;
const timer = setInterval(() => {
count++;
console.log(`${count}초 경과`);
}, 1000);
타이머 중지하기
let count = 0;
const timer = setInterval(() => {
count++;
console.log(`${count}초 경과`);
if (count >= 5) {
clearInterval(timer);
console.log('인터벌 종료');
}
}, 1000);
실용 예제: 시계
function displayClock() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
console.log(`${hours}:${minutes}:${seconds}`);
}
const clockTimer = setInterval(displayClock, 1000);
displayClock();
3. 중첩 setTimeout
3-1. setInterval의 문제점
setInterval은 함수 실행 시간을 고려하지 않고 일정한 간격으로 함수를 호출합니다.
setInterval(() => {
// 이 작업이 2초 걸린다면?
heavyTask(); // 2초 소요
}, 1000); // 1초마다 실행 요청
함수가 끝나기 전에 다음 인터벌이 실행될 수 있습니다.
비동기 작업에서는 중복 실행 문제가 생기기 쉽습니다.
3-2. 중첩 setTimeout의 장점
중첩 setTimeout은 함수 실행이 끝난 후 다음 실행을 예약할 수 있습니다.
function repeatTask() {
console.log('작업 실행');
setTimeout(repeatTask, 1000);
}
setTimeout(repeatTask, 1000);
예제: 에러 발생 시 재시도 간격 늘리기
let delay = 1000;
function fetchData() {
const success = Math.random() > 0.3;
if (success) {
delay = 1000;
setTimeout(fetchData, delay);
} else {
delay *= 2;
if (delay > 16000) {
delay = 16000;
}
setTimeout(fetchData, delay);
}
}
fetchData();
3-3. setInterval vs 중첩 setTimeout
setInterval
시작 → [1초] → 함수 실행(2초 소요) → 함수 실행(중복) → ...
함수 실행 시간과 관계없이 일정 간격으로 호출됩니다.
함수가 끝나지 않아도 다음 호출이 쌓일 수 있습니다.
중첩 setTimeout
시작 → [1초] → 함수 실행(2초 소요) → [1초] → 함수 실행 → ...
함수가 완전히 끝난 후 다음 실행을 예약합니다.
중복 실행을 방지하기 쉽습니다.
| 비교 항목 | setInterval | 중첩 setTimeout |
|---|---|---|
| 호출 간격 | 무조건 일정 | 실행 완료 후 대기 |
| 실행 시간 보장 | 보장 안 됨 | 보장됨 |
| 안정성 | 낮음 | 높음 |
| 중복 실행 위험 | 있음 | 없음 |
| 유연성 | 고정 간격만 가능 | 동적으로 간격 조절 가능 |
| 사용 추천 | 단순 반복 작업 | 비동기/무거운 작업 |
3-4. 언제 무엇을 사용해야 하나?
setTimeout 사용
일회성 지연 실행
디바운싱/쓰로틀링
조건부 반복
비동기 작업 반복
setInterval 사용
매우 가벼운 작업의 단순 반복
정확한 시간 간격이 중요한 애니메이션
실시간 시계/카운터
중첩 setTimeout 사용
서버 요청 같은 비동기 작업 반복
실행 시간이 불규칙한 작업
에러 시 재시도 로직
실행 간격을 동적으로 조절해야 할 때
4. 참고
setTimeout(0)은 정확히 0초 뒤에 실행된다는 의미가 아닙니다.
타이머 콜백은 현재 실행 중인 작업이 끝난 뒤 이벤트 루프를 통해 실행됩니다.
브라우저는 중첩 타이머가 과도하게 CPU를 점유하지 않도록 최소 지연 시간을 둘 수 있습니다.
HTML 표준에서는 중첩 타이머에 대해 최소 4ms 지연이 적용될 수 있음을 설명합니다.
참고 문서: HTML Standard - Timers

댓글 0