본래 함수를 명시적으로 호출하면 함수가 즉시 실행되지만, 호출 스케쥴링으로 함수 호출을 예약함.
- 자바스크립트 엔진은 싱글 스레드 ⇒ 태스크를 동시에 실행할수 없고, 타이머 함수는 비동기 처리 방식으로 동작한다.
- 즉,
setTimeout()은 함수 스택의 다른 함수 호출을 막지 않음
setTimeout(function () {
console.log("Hello World!");
}, 500);
//this 문제를 방지하기위해 화살표로 작성
setTimeout(() => {
console.log("hello world" ;
}, 2000);
중첩 타임 아웃
HTML 표준에 명시된 것과 같이, 브라우저는 setTimeout 호출이 5번 이상 중첩된 경우 4ms의 최소 지연 시간을 강제함.
setTimeout은 생성된 타이머를 식별할 수 있는 고유한 타이머 id를 반환( 숫자 or 객체)
해당 id를 clearTimeout 함수의 인수로 전달하여 타이머를 취소할 수 있다
clearTimeout(timeoutID)
setInterval 는 생성된 타이머를 식별할 수 있는 고유한 타이머 아이디를 반환 (숫자 or 객체)setInterval가 반환한 타이머 id 를 clearInterval() 함수의 인수로 전달하여 타이머를 취소한다.scroll, resize, input, mousemove 같이 자주 일어나는 이벤트에 바인딩한 이벤트 핸들러에는 디바운스와 스로틀을 이용
위의 이벤트를 그룹화 해서 과도한 이벤트 핸들러의 호출을 방지하는 프로그래밍 기법 이다.
일정 시간이 경과한 이후에 이벤트 핸들러가 한번만 호출되도록 한다.
디바운스는 이벤트를 그룹화 해서 마지막에 한번만 이벤트 핸들러가 호출 되도록 함.
전달한 시간보다 짧은 간격으로 이벤트가 발생하면 이전 타이머를 취소하고 새로운 타이머를 재 설정 한다. 따라서 딜레이 보다 짧은 간격으로 이벤트가 연속해서 발생하면 디바운스 함수의 첫번째 인수로 전달한 콜백 함수는 호출 되지않다가 딜레이 동안 이벤트가 더이상 발생하지 않으면 한번만 호출 된다.
일정 시간 간격으로 이벤트 핸들러가 최대 한번만 호출되도록 한다.
즉 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화 해서 일정 시간 단위로 핸들러가 호출되도록 호출 주기를 만든다.
두번째 인수로 전달한 시간이 경과하기 이전에 이벤트가 발생하면 아무것도 하지 않다가 딜레이 시간이 경과했을때 이벤트가 발생하면 콜백 함수를 호출하고 새로운 타이머를 재 설정한다.
scrollEvent, 무한 스크롤 등에 유용하게 사용된다.
사용자가 60hz를 사용하던 144hz를 사용하던 상관없이 사용자의 디스플레이에 맞춰진다.
requestAnimationFrame을 사용하면 페이지가 비활성화인 상태일 때 repaint 작업이 멈춘다.
애니메이션이 일시중지 되므로 CPU 리소스를 낭비하지 않는다.
Event Loop에는 Animation Frames라는 requestAnimationFrame 전용 Queue가 존재한다.
https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame
requestAnimationFrame(콜백함수)
export default function Test() {
const [scale, setScale] = useState(1);
useEffect(() => {
let ticking = false;
const handleScroll = () => {
if (!ticking) {
requestAnimationFrame(() => {
const scrollY = window.scrollY;
const newScale = 1 + Math.min(scrollY / 500, 0.3); // 최대 1.5배로 설정
setScale(newScale);
ticking = false;
});
ticking = true;
}
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return (
<Contents>
<Empty />
<TestStyle scale={scale}>
<img src={Img} />
</TestStyle>
</Contents>
);
}
setTimeout을 활용한 Recursive PollinguseEffect(() => {
let isActive = true;
const fetchData = async () => {
if (!isActive) return;
await ~~~함수내용
if (isActive) {
setTimeout(fetchData, 5000); // 5초 후 다시 실행
}
};
fetchData(); // 초기 실행
return () => {
isActive = false; // 언마운트 시 정리
};
}, []);