코드 품질을 높여주는 유용한 자바스크립트 함수 - (1)

JeBread·2024년 3월 28일
0

WEB

목록 보기
4/10
post-thumbnail

자바스크립트는 강력하고 다재다능한 프로그래밍 언어이며 보다 효율적이고, 유지 보수가 용이하며, 가독성이 높은 코드를 작성하는 데 도움이 되는 기능들을 많이 내장하고 있습니다.

이 글에서는, 내장된 기능을 사용해 성능을 향상하고 코드를 더 멋지게 보이도록 하는 아주 강력한 함수들을 만드는 방법을 설명하려고 합니다. 이는 자바스크립트 작업을 더욱 즐겁고 효율적으로 만들어 줍니다. 자바스크립트 개발자로서 코드 품질을 최적화하기 위해 유틸리티 파일/클래스에 저장할 수 있는 Debounce, Throttle, Once, Memoize, Curry, Partial, Pipe, Compose, Pick, Omit, 그리고 Zip까지 다뤄보겠습니다.

Debounce

debounce 함수는 일련의 빠른 이벤트가 반복적으로 함수를 활성화하는 것을 방지하는 역할을 합니다. 이벤트가 실행되지 않은 채로 일정 시간이 경과할 때까지 이벤트를 실행시키지 않고 함수의 실행을 연기하는 방식으로 동작합니다. debounce 함수는 사용자가 버튼을 빠르게 클릭했을 때 함수들이 실행되는 것을 방지하여 성능을 향상하는 방식으로 실제 애플리케이션에서 적용될 수 있는 아주 유용한 해결책입니다.

다음 코드 스니펫은 어떻게 자바스크립트로 debounce 함수를 구현하는지를 보여줍니다.

function debounce(func, delay) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(context, args), delay);
  };
}

이 자바스크립트 코드에서, debounce 함수는 이전에 정의된 delay만큼 지연을 시키고, 원래 함수를 실행하는 새로운 함수를 반환합니다. 만약 함수가 다시 호출되는 경우, timeout은 초기화되며 함수의 호출이 연기됩니다.

이러한 기능은 윈도우 창의 크기가 조정될 때 웹페이지의 레이아웃을 업데이트하는 함수가 있는 경우 아주 유용합니다. Debounce 함수가 없다면, 사용자가 창의 크기를 변경할 때마다 아주 빠르게 연속적으로 함수가 호출될 것이며, 이는 성능 문제를 유발할 수 있습니다. Debounce 함수가 있다면, 레이아웃이 업데이트되는 속도를 제한할 수 있어 웹페이지의 반응성과 효율성을 높여줍니다.

다음 스니펫은 위에서 언급한 사례에서 어떻게 Debounce 함수가 사용되는 방식을 보여줍니다.

// 레이아웃을 업데이트하는 함수 정의
function updateLayout() {
  // 레이아웃 업데이트...
}

// 디바운스된 함수를 생성
const debouncedUpdateLayout = debounce(updateLayout, 250);

// 윈도우의 리사이즈 이벤트를 받아 디바운스된 함수를 호출
window.addEventListener("resize", debouncedUpdateLayout);

이 예제에서, 윈도우 창 크기가 변경되었을 때 updateLayout 함수는 최대 250밀리초마다 한 번씩만 호출됩니다. 즉, 사용자가 창 크기 변경을 완료한 뒤 250밀리초 후에 레이아웃이 업데이트 됩니다. 이를 통해 웹페이지의 효율성과 반응성이 향상됩니다.

Throttle

Throttle 함수는 Debounce 함수와 비슷하지만 동작에 약간의 차이가 있습니다. Debounce 함수는 특정 함수가 호출되는 속도를 제한하지만, Throttle 함수는 특정 함수가 실행되는 속도를 제한하는 것이죠. 즉, 특정 기간 내에 어떤 함수를 이미 호출했다면 그 함수가 실행되는 것을 막는 역할을 합니다. 특정 함수가 일정한 속도로 실행되고 너무 자주 트리거 되지 않게 보장해 줍니다.

Throttle 함수의 구현은 다음과 같습니다.

function throttle(func, delay) {
  let wait = false;

  return (...args) => {
    if (wait) {
        return;
    }

    func(...args);
    wait = true;
    setTimeout(() => {
      wait = false;
    }, delay);
  }
}

이 스니펫에서, throttle 함수는 주어진 func 함수를 실행하고, wait 변수를 true로 갱신한 후에, 타이머를 시작합니다. 이 타이머는 delay만큼의 시간이 흐르면 wait 파라미터를 다시 초기화합니다. 만약 throttle 함수가 다시 호출된다면, wait 파라미터가 true라면 그냥 리턴하고 아니라면 주어진 함수를 다시 호출하게 됩니다.

웹페이지에서 스크롤 하는 동안 레이아웃을 업데이트하는 함수를 실행시키고자 할 때 이 throttle 기능을 사용할 수 있습니다. throttle 함수가 없다면, 레이아웃을 업데이트하는 함수는 사용자가 페이지를 스크롤 할 때마다 여러 번 호출되는데, 이는 아주 심각한 성능 문제를 야기시킬 수도 있습니다. throttle 함수를 사용하여, 함수가 X 밀리초마다 딱 한 번만 실행되도록 보장할 수 있습니다. 이를 통해 웹페이지의 사용성을 좀 더 반응적이고 효율적으로 만들어 냅니다.

다음 스니펫에서, 여러분들은 throttle 함수가 사용되는 방식을 볼 수 있습니다.

// 레이아웃을 업데이트하는 함수 정의
function updateLayout() {
  // 레이아웃 업데이트...
}

// 함수의 스로틀된 버전 생성
const throttledUpdateLayout = throttle(updateLayout, 250);

// 윈도우 창의 스크롤 이벤트가 발생하면 스로틀된 함수를 실행
window.addEventListener("scroll", throttledUpdateLayout);

throttleUpdatedLayout 함수를 정의하고 250밀리초를 지연시간으로 설정하면, 윈도우 창이 스크롤 될 때 updateLayout 함수가 최대 250밀리초마다 한 번씩만 실행되도록 할 수 있습니다. 지연 시간이 끝나기 전에 이벤트가 발생하면 아무 일도 일어나지 않습니다.

Once

Once 함수는 이미 호출된 함수가 다시 실행되지 않도록 하는 메서드 입니다. 이 메서드는 특히 이벤트 리스너를 이용하여 작업하는 동안, 오직 한 번만 실행해야 하는 함수가 자주 있는 경우 유용합니다. 매번 이벤트 리스너를 제거하는 대신 Once 함수를 사용하면 됩니다.

function once(func) {
  let ran = false;
  let result;
  return function() {
    if (ran) return result;
    result = func.apply(this, arguments);
    ran = true;
    return result;
  };
}

예를 들어, 어떤 데이터를 로드하기 위해 서버에 요청을 보내는 함수가 있을 수 있습니다. once() 함수를 이용해서, 사용자가 버튼을 계속 눌렀을 때 요청이 여러 번 호출되지 않도록 만들 수 있습니다. 이는 성능 문제를 해결합니다.

once() 함수가 없다면, 요청을 다시 보내는 것을 막기 위해 요청을 보내고 나서 바로 클릭 리스너를 제거해야 할 겁니다.

once() 함수를 코드에 적용하면 다음과 같습니다.

// 요청을 보내는 함수 정의
function requestSomeData() {
  // 요청을 보냄
}

// 한 번만 호출될 수 있는 requestSomeData 생성
const sendRequestOnce = once(sendRequest);

// 버튼의 클릭 이벤트가 발생하면 "once" 함수를 호출
const button = document.querySelector("button");
button.addEventListener("click", sendRequestOnce);

이 예제에서, requestSomeData 함수는 사용자가 버튼을 여러 번 누를지라도 딱 한 번만 호출됩니다.

오늘은 여기까지 설명하고 다음 2편은 다음 시간에 작성해보겠습니다.

0개의 댓글

관련 채용 정보