🚀 94sssh
Published on

2024.10.05

[딥다이브] - 41. 타이머

41.1. 호출 스케줄링

호출 스케줄링: 함수를 명시적으로 호출하지 않고 시간이 경과된 후에 호출되도록 함수 호출을 예약하는 것

  • 타이머를 생성할 수 있는 함수: setTimeout, setInterval
  • 타이머를 제거할 수 있는 함수: clearTimeout, clearInterval

타이머 함수는 호스트 객체로 브라우저 환경과 Node.js 환경에서 모두 제공한다.

자바스크립트 엔진은 싱글 스레드로 동작하기에, setTimeoutsetInterval은 비동기 처리 방식으로 동작한다.

41.2. 타이머 함수

41.2.1. setTimeout / clearTimeout

setTimeout 함수는 두 번째 인수로 전달받은 시간 이후 한 번 콜백 함수가 호출된다.

const timeoutId = setTimeout(func|code[, delay, param1, param2, ...])
// 1초 후 콜백 함수 호출
setTimeout(() => console.log('Hi'), 1000)

// 1초 후 콜백 함수 호출, 콜백 함수에 인수 전달
setTimeout((name) => console.log(name), 1000, 'Han')

// 딜레이를 생략하면 기본값 0이 지정
setTimeout(() => console.log('Hi'))

delay가 4ms 이하인 경우 최소 지연 시간 4ms가 지정된다.

setTimeout 함수는 고유한 타이머 id를 리턴한다. 타이머 id를 clearTimeout에 전달하여 타이머를 취소할 수 있다.

타이머 is는 브라우저 환경인 경우 숫자이며, Node.js 환경인 경우 객체다.

const timerId = setTimeout(() => console.log('Hi'), 1000)

// 타이머를 취소하여 콜백 함수가 실행되지 않는다.
clearTimeout(timerId)

41.2.2. setInterval / clearInterval

setInterval 함수는 두 번째 인수로 전달받은 시간이 경과할 때마다 콜백 함수가 반복 호출된다.

const timeoutId = setInterval(func|code[, delay, param1, param2, ...])

setInterval도 setTimeout과 동일하게 타이머 id를 리턴하며 clearInterval에 전달해 타이머를 취소할 수 있다.

41.3. 디바운스와 스로틀

디바운스와 스로틀은 짧은 시간 간격으로 연속 발생하는 이벤트를 그룹화해 과도한 호출을 방지하는 기법이다.

41.3.1. 디바운스

디바운스는 짧은 시간 간격으로 발생하는 이벤트를 그룹화해 마지막에 한 번만 이벤트 핸들러를 호출한다.

const debounce = (callback, delay) => {
  let timerId
  // debounce는 timerId를 기억하는 클로저를 리턴
  return (...args) => {
    // delay 경과 전 이벤트 발생 시 이전 타이머를 취소하고 새로운 타이머를 재설정한다.
    if (timerId) clearTimeout(timerId)
    timerId = setTimeout(callback, delay, ...args)
  }
}

debounce 함수가 리턴한 함수는 딜레이보다 짧은 간격으로 이벤트가 발생하면 이전 타이머를 취소하고 새로운 타이머를 재설정한다.
디바운스는 resize 이벤트 처리나 input 요소에 입력된 값으로 ajax 요청하는 입력 필드 자동완성 UI 구현, 버튼 중복 클릭 방지 처리 등에 사용된다.

41.3.2. 스로틀

스로틀은 짧은 시간 간격으로 연속 발생하는 이벤트를 그룹화해 일정 시간 단위로 이벤트 핸들러가 호출되도록 호출 주기를 만든다.

const throttle = (callback, delay) => {
  let timerId
  // throttle은 timerId를 기억하는 클로저를 리턴
  return (...args) => {
    // delay 간격으로 callback이 호출
    if (timerId) return
    timerId = setTimeout(() => {
      callback(...args)
      timerId = null
    }, delay)
  }
}

throttle 함수가 리턴한 함수는 딜레이가 경과하기 전에 이벤트가 발생하면 아무것도 하지 않다가 딜레이가 경과했을 때 이벤트가 발생하면 콜백 함수를 호출하고 새로운 타이머를 재설정한다. 스로틀은 scroll 이벤트 처리나 무한 스크롤 UI 구현 등에 사용된다.