모자딥 41장 타이머

릿·2023년 2월 10일
0

41. 타이머

41.1 호출 스케줄링


  • 호출 스케줄링: 함수를 일정 시간이 경과된 이후에 호출되도록 함수 호출을 예약하기 위해 타이머 함수를 사용하는 것

41.2 타이머 함수


41.2.1 setTimeout / clearTimeout

  • setTimeout함수의 콜백함수는 두번째 인수로 전달받은 시간 이후 단 한번 실행되도록 호출 스케줄링 됨
const timeoutId = setTimeout(func|code[, delay, param1, param2, ...]);

// 1초(1000ms) 후 타이머가 만료되면 콜백 함수가 호출됨
setTimeout(() => console.log('Hi!'), 1000);

// 1초(1000ms) 후 타이머가 만료되면 콜백 함수가 호출됨
// 이 때 콜백 함수에 'Lee'가 인수로 전달됨
setTimeout(name => console.log(`Hi! ${name}.`), 1000, 'Lee');
  • clearTimeout함수는 호출 스케줄링을 취소함
const timerId = setTimeout(() => console.log('Hi!'), 1000);

clearTimeout(timerId);

41.2.2 setInterval / clearInterval

  • setInterval함수의 콜백 함수는 두번째 인수로 전달받은 시간이 경과할 때마다 반복 실행되도록 호출 스케줄링 됨
const timerId = setInterval(func|code[, delay, param1, param2, ...]);
  • clearInterval함수는 호출 스케줄링을 취소함
let count = 1;

const timeoutId = setInterval(() => {
  console.log(count); // 1 2 3 4 5
  if (count++ === 5) clearInterval(timeoutId);
}, 1000);

41.3 디바운스와 스로틀


  • 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 과도한 이벤트 핸들러 호출을 방지하는 프로그래밍 기법

41.3.1 디바운스

  • 짧은 시간 간격으로 이벤트를 그룹화해서 마지막에 한번만 이벤트 핸들러가 호출되도록 함
...
  const debounce = (callback, delay) => {
    let timerId;
    // debounce함수는 timerId를 기억하는 클로저를 반환
    return event => {
      if (timerId) clearTimeout(timerId);
      timerId = setTimeout(callback, delay, event);
    };
  };
  
  // debounce함수가 반환하는 클로저가 이벤트 핸들러로 등록됨
  // 300ms보다 짧은 간격으로 input 이벤트가 발생하면 콜백함수가
  // 호출되지 않다가 300ms동안 input 이벤트가 더 이상 발생하지 않으면 한번만 호출됨
  $input.oninput = debounce(e => {
    $msg.textContent = e.target.value;
  }, 300);
...
  • 실무에서는 Underscore의 debounce함수나 Lodash의 debounce함수를 사용하는 것을 권장함

41.3.2 스로틀

  • 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 일정 시간 단위로 이벤트 핸들러가 호출되도록 호출주기를 만듦
...
  const throttle = (callback, delay) => {
    let timerId;
    // throttle함수는 timerId를 기억하는 클로저를 반환함
    return event => {
    	// delay가 경과하기 전에 이벤트가 발생하면 아무것도 하지 않다가
        // delay가 경과했을 때 이벤트가 발생하면 새로운 타이머를 재설정함
        // 따라서 delay 간격으로 callback이 호출됨
        if (timerId) return;
        timerId = setTimeout(() => {
          callback(event);
          timerId = null;
        }, delay, event);
    };
  };
  
  ...
  $container.addEventListener('scroll', throttle(() => {
    $throttleCount.textContent = ++throttleCount;
  }, 100));
  ...
...
  • 실무에서는 Underscore의 throttle함수나 Lodash의 throttle함수를 사용하는 것을 권장함
profile
항상 재밌는 뭔가를 찾고 있는 프론트엔드 개발자

0개의 댓글