728x90
반응형
1. 타이머 함수란
타이머 함수는 일정 시간 후 또는 주기적으로 코드를 실행하기 위한 글로벌 함수입니다. Node.js의 타이머는 브라우저의 타이머 API와 유사하지만, 이벤트 루프와 밀접하게 연관되어 있습니다. setTimeout, setInterval, setImmediate, process.nextTick이 주요 타이머 함수입니다.
2. setTimeout
지정된 시간 후 콜백 함수를 한 번 실행합니다.
2.1 기본 사용법
// 2초 후 실행
setTimeout(() => {
console.log('2초 후 실행됨');
}, 2000);
// 인자 전달
setTimeout((name, age) => {
console.log(`이름: ${name}, 나이: ${age}`);
}, 1000, '홍길동', 30);
2.2 타이머 취소
const timerId = setTimeout(() => {
console.log('이 메시지는 출력되지 않습니다');
}, 5000);
// 타이머 취소
clearTimeout(timerId);
2.3 Promise 기반 타이머 (Node.js 15+)
const { setTimeout } = require('timers/promises');
async function delay() {
console.log('시작');
await setTimeout(2000);
console.log('2초 후');
// 값 반환
const result = await setTimeout(1000, '완료');
console.log(result); // 완료
}
delay();
3. setInterval
지정된 간격으로 콜백 함수를 반복 실행합니다.
3.1 기본 사용법
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log(`실행 횟수: ${count}`);
// 5번 후 중지
if (count >= 5) {
clearInterval(intervalId);
console.log('반복 종료');
}
}, 1000);
3.2 타이머 취소
const intervalId = setInterval(() => {
console.log('매 초마다 실행');
}, 1000);
// 5초 후 인터벌 취소
setTimeout(() => {
clearInterval(intervalId);
console.log('인터벌 취소됨');
}, 5000);
3.3 Promise 기반 반복 타이머 (Node.js 15+)
const { setInterval } = require('timers/promises');
async function periodicTask() {
let count = 0;
for await (const _ of setInterval(1000)) {
count++;
console.log(`반복 ${count}`);
if (count >= 5) break;
}
}
periodicTask();
4. setImmediate
현재 이벤트 루프 사이클이 완료된 후 콜백을 실행합니다.
4.1 기본 사용법
console.log('1: 시작');
setImmediate(() => {
console.log('3: setImmediate');
});
console.log('2: 끝');
// 출력 순서: 1 → 2 → 3
4.2 setTimeout(0)과의 차이
setImmediate(() => {
console.log('setImmediate');
});
setTimeout(() => {
console.log('setTimeout');
}, 0);
// 실행 순서는 상황에 따라 다를 수 있음
// I/O 콜백 내부에서는 setImmediate가 항상 먼저 실행됨
4.3 I/O 콜백 내부에서의 실행 순서
const fs = require('fs');
fs.readFile('file.txt', () => {
setTimeout(() => {
console.log('setTimeout');
}, 0);
setImmediate(() => {
console.log('setImmediate');
});
});
// I/O 콜백 내부에서는 항상:
// setImmediate → setTimeout 순서
4.4 Promise 기반 (Node.js 15+)
const { setImmediate } = require('timers/promises');
async function immediate() {
await setImmediate();
console.log('즉시 실행 (다음 틱)');
}
5. process.nextTick
현재 작업이 완료된 직후, 이벤트 루프 다음 단계 전에 콜백을 실행합니다.
5.1 기본 사용법
console.log('1: 시작');
process.nextTick(() => {
console.log('2: nextTick');
});
console.log('3: 끝');
// 출력 순서: 1 → 3 → 2
5.2 실행 순서 비교
console.log('1: 동기');
setTimeout(() => console.log('5: setTimeout'), 0);
setImmediate(() => console.log('6: setImmediate'));
Promise.resolve().then(() => console.log('3: Promise'));
process.nextTick(() => console.log('2: nextTick'));
console.log('4: 동기');
// 출력 순서: 1 → 4 → 2 → 3 → 5/6 (5와 6은 상황에 따라 다름)
5.3 재귀 호출 주의
// 잘못된 사용 - 이벤트 루프 블로킹
function badRecursion() {
process.nextTick(badRecursion); // 무한 루프!
}
// 올바른 사용 - setImmediate 사용
function goodRecursion() {
setImmediate(goodRecursion); // 다른 작업 처리 가능
}
반응형
6. 타이머 객체 메서드
6.1 ref(), unref()
const timer = setTimeout(() => {
console.log('실행됨');
}, 10000);
// unref: 이 타이머가 프로세스를 유지하지 않음
timer.unref();
// 다른 작업이 없으면 프로세스가 종료됨
console.log('프로세스가 바로 종료될 수 있음');
// ref: 다시 프로세스를 유지하도록 설정
timer.ref();
6.2 refresh()
const timer = setTimeout(() => {
console.log('실행됨');
}, 5000);
// 2초 후 타이머 재시작 (다시 5초 대기)
setTimeout(() => {
timer.refresh();
console.log('타이머 재시작');
}, 2000);
7. 실전 활용 예시
7.1 디바운스 (Debounce)
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
const search = debounce((query) => {
console.log('검색:', query);
}, 300);
search('h');
search('he');
search('hel');
search('hell');
search('hello'); // 마지막 호출만 실행됨
7.2 쓰로틀 (Throttle)
function throttle(func, limit) {
let inThrottle;
return function (...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
const handleScroll = throttle(() => {
console.log('스크롤 처리');
}, 1000);
7.3 재시도 로직
async function fetchWithRetry(url, maxRetries = 3, delay = 1000) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url);
return await response.json();
} catch (err) {
if (i === maxRetries - 1) throw err;
console.log(`재시도 ${i + 1}/${maxRetries}...`);
await new Promise(resolve => setTimeout(resolve, delay * (i + 1)));
}
}
}
결론
Node.js의 타이머 함수는 비동기 작업 스케줄링의 핵심 도구입니다. setTimeout은 지연 실행, setInterval은 반복 실행, setImmediate는 현재 이벤트 루프 완료 후 실행, process.nextTick은 현재 작업 직후 실행에 사용됩니다. Node.js 15+에서는 timers/promises를 통해 Promise 기반으로 더 깔끔하게 사용할 수 있습니다.
728x90
반응형
'Node.js' 카테고리의 다른 글
| Node.js의 콘솔 객체(console object) (0) | 2026.02.25 |
|---|---|
| Node.js의 프로세스 객체(process object) (0) | 2026.02.25 |
| Node.js의 글로벌 객체(Global Objects) (0) | 2026.02.24 |
| Node.js의 버퍼(Buffer) 사용법 (0) | 2026.02.24 |
| Node.js의 스트림 모듈(stream module) (0) | 2026.02.24 |