함수가 즉시 실행되도록 하지 않고, 일정 시간이 경과되면 실행되도록 하려면 타이머 함수를 사용하면 된다.
자바스크립트는 두 가지의 타이머 생성 함수를 제공한다.
자바스크립트 엔진은 단 하나의 실행 컨텍스트 스택을 갖기 때문에 두 가지 이상의 태스크를 동시에 실행할수 없다. 즉, 자바스크립트 엔진은 싱글 스레드로 동작한다. 이런 이유로, 타이머함수들은 비동기 처리 방식으로 동작한다.
디바운스는 짧은 시간 간격으로 이벤트가 연속해서 발생하면, 이벤트를 호출하지 않다가, 일정 시간이 경과한 이후에 이벤트 핸들러가 한 번만 호출되도록 한다.
사용하면 좋은 예: 텍스트 입력 필드에서 input 이벤트가 짧은 시간 간격으로 연속해서 발생하는 경우.
스로틀은 짧은 시간 간격으로 이벤트가 연속해서 발생하더라도 일정 시간 간격으로 이벤트 핸들러가 최대 한번만 호출되도록 한다.
사용하면 좋은 예: scroll이벤트가 짧은 시간 간격으로 연속해서 발생하는 경우.
분명 자바스크립트 엔진은 싱글 스레드라고 했는데 어떻게 타이머 함수가 비동기적으로 동작할 수 있을까?
이유는 자바스크립트 엔진은 싱글 스레드로 동작하지만 브라우저는 멀티스레드로 동작하기 때문이다.
setTimeout 같은 타이머 함수, ajax 등의 비동기 처리들은 자바스크립트 엔진이 하는 게 아니라 브라우저에 내장되어있는 Web API가 담당한다.
(그림 출처:https://baeharam.netlify.app/posts/javascript/event-loop)
- 자바스크립트 엔진은 콜 스택 최상단에 있는 실행 컨텍스트의 소스코드를 쭉 실행하다가 비동기 처리가 되야 할 함수(콜백함수,이벤트 핸들러 등)들을 만나면 해당 함수들을 호출 스케줄링하고 다음 코드로 넘어간다.
- 브라우저는 호출 스케줄링된 함수들을 감시하고 있다가 조건(타이머 시간 경과 등)이 만족되면 함수를 테스크 큐에 넣는다.
- 이벤트 루프는 테스크 큐를 계속 감시하고 있다가 테스크 큐에 대기중인 함수가 있다면 콜 스택이 비어있는지 확인하고 비어있다면 콜스택에 넣는다.
- 1,2,3을 반복하며 콜 스택 최상단에 있는 컨택스트들을 실행한다.